全球运营商必须非常具体地编写,否则它不会被链接

时间:2015-04-07 06:53:31

标签: c++ templates operator-overloading

我正在尝试为自定义容器编写自定义随机访问迭代器。迭代器和容器都工作正常,但烦人的部分是迭代器比较。如果定义如下:

template <typename T>
class my_iterator {...}

template <typename T>
bool operator< (const my_iterator<T>&, const my_iterator<T>&) {...}

当我想比较迭代器时,比如在这种情况下:

for (my_iterator<T> i = foo.begin(); i < foo.end(); ++i) //Unresolved external error

我不得不写:

for (my_iterator<T> i = foo.begin(); operator< <T>(i, foo.end()); ++i) //Looks weird

如果我不使用第二种方式,它会给我一个荒谬的未解决的外部词呕吐错误。

我怎样才能使用普通语法进行比较?

编辑:我发现了导致错误的原因,但我并不理解为什么。这堂课看起来像:

template <typename T>
class my_iterator {
    friend bool operator< (const my_iterator<T>&, const my_iterator<T>&);
};

我的朋友声明错了,应该是:

friend bool operator< <T>(const my_iterator<T>&, const my_iterator<T>&);

当操作符更像是函数调用时,为什么不正确的朋友声明会起作用,但通常不正常?

1 个答案:

答案 0 :(得分:0)

您可以先声明模板,以便编译器知道您在类范围内声明的朋友operator<是模板:

template <typename T>
class my_iterator;

template <typename T>
bool operator< (const my_iterator<T>&, const my_iterator<T>&);

template <typename T>
class my_iterator {
    // Note the "<>" here, this means "I'm a template"
    friend bool operator< <> (const my_iterator<T>&, const my_iterator<T>&);
    // ...
};

template <typename T>
bool operator< (const my_iterator<T>&, const my_iterator<T>&)
{
    // ...
}

否则,它将被解析为非模板友元函数声明(您不定义),因此链接器错误。见http://isocpp.org/wiki/faq/templates#template-friends

另一个选择是成员operator<

template <typename T>
class my_iterator {
    bool operator< (const my_iterator<T>& rhs) const
    {
        return this->impl < rhs.impl;
    }

    // ...
};