我编写了一种方法,该方法可以自动内插C++中昂贵的2D函数。我现在试图允许类接受函数指针,以便可以对任何函数进行插值。为此,看来我需要一个模板化的类,以便可以为需要对其评估函数指针的每个对象进行模板化。在意识到我需要完全在头文件中定义类之后,链接器可以为所需的每个对象模板化该类,这一部分还不错。现在擦。
在该类中,我使用boost::unordered_map来存储函数求值,这样就不必调用该函数了。在插值过程中,我细化了一个网格,使其能够充分描述它(基于其曲率)。我在局部细分网格,因此,如果我的原始点位于x = 0,.5、1,则下一组可能是x = 0,.25,.5、1,在这里我只需要评估为第二遍x = .25。它可以使用硬编码函数来代替动态函数指针来单独工作。
我遇到的麻烦是为boost::tuple定义了必需的运算符和hash_value函数。如果我将其放在标题中,则会多次定义(对于标题的每个包含)。如果我尝试将其编译为对象并进行链接,则链接器将无法找到定义。我需要在该类中引用两个定义:
bool operator==(const BoostTuple2D &a, const BoostTuple2D &b)
{
return a.tuple.get<0>() == b.tuple.get<0>() &&
a.tuple.get<1>() == b.tuple.get<1>();
}
std::size_t hash_value(const BoostTuple2D &e)
{
std::size_t seed = 0;
boost::hash_combine(seed, e.tuple.get<0>());
boost::hash_combine(seed, e.tuple.get<1>());
return seed;
}
在我的 header 中,我有一个struct和typedef:
struct BoostTuple2D {
BoostTuple2D(double x1, double x2)
: tuple(x1, x2) {}
boost::tuples::tuple<double, double> tuple;
};
typedef boost::unordered_map< BoostTuple2D, double > BoostTuple2DMap;
这是在我的模板化类之上,带有省略项:
template<class F>
class Interpolate {
public:
class Evaluate {
// this class uses the map to cache evaluations of the dynamic pointer
}
Interpolate (double (F::*f)(double, double), F & obj, [...]) : f(f), object(obj), ... {};
private:
// members
};
如何使operator ==和hash_value方法可用于该类,而无需多次定义它们?我在守护头文件。我是c++新手,所以希望它不会变得简单。谢谢!
最佳答案
对于 header 中的非模板方法,您需要在它们之前加上关键字“inline”。虽然不能保证函数会内联(在这种情况下只是提示),但它确实要求链接器允许多个定义。
inline bool operator==(const BoostTuple2D &a, const BoostTuple2D &b)
{
return a.tuple.get<0>() == b.tuple.get<0>() &&
a.tuple.get<1>() == b.tuple.get<1>();
}
std::size_t hash_value(const BoostTuple2D &e)
{
std::size_t seed = 0;
boost::hash_combine(seed, e.tuple.get<0>());
boost::hash_combine(seed, e.tuple.get<1>());
return seed;
}
如果您在将它们放置在自己的源文件中时遇到问题,但是将声明保留在hedaer中,则您将它们放入的 namespace 可能存在问题。我必须查看该版本的代码以提供帮助。
注意,元组应该已经定义了
operator==
,因此您可以使用它而不是自己逐个比较元素(默认情况下已经做到了)。