模板化类中的boost :: unordered_map中的boost :: tuple问题

时间:2013-08-27 14:47:12

标签: c++ boost function-pointers unordered-map class-template

我编写了一种方法,可以在C ++中自动插入昂贵的2D函数。我现在正在尝试允许类接受函数指针,以便可以插入任何函数。要做到这一点,似乎我需要一个模板化的类,以便我可以为每个对象模板化它需要评估函数指针。在我意识到我需要完全在头文件中定义类之后,那部分并不是那么糟糕,以便链接器可以为所需的每个对象模板化类。现在好了。

在类中我使用boost :: unordered_map来存储函数评估,这样我就不会不必要地调用函数。在插值期间,我精炼网格,以便充分描述它(基于其曲率)。我在局部细分网格,所以如果我的原始点在x = 0,.5,1,那么下一组可能是x = 0,.25,.5,1,我只需要在第二遍x = .25。这是用自己的硬编码函数来代替动态函数指针。

我遇到的麻烦是为boost :: tuple定义必要的operator和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;
}

在我的标题中,我有一个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
};

如何让class ==和hash_value方法可用于类而无需多次定义它们?我正在守护头文件。我是一个c ++ newbee,所以希望它简单,我没有得到。谢谢!

1 个答案:

答案 0 :(得分:1)

如果标题中包含非模板方法,则需要在其前面加上关键字“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中,则可能存在您将它们放入的命名空间的问题。我将不得不看到该版本的代码帮助。

作为一个注释,元组应该已经定义了operator==,所以你可以使用它而不是自己逐个元素地比较(默认已经这样做了)。