重载运算符==使用一个带模板化迭代器的自由函数

时间:2015-03-18 05:48:48

标签: c++ templates c++11 operator-keyword typename

所以我试图创建一个比较两个迭代器的函数,但我不确定如何正确使用模板。 班级

template<typename Key_T, typename Mapped_T>
class Map{...}

免费功能

bool operator==(const Map::Iterator &iter1, const Map::Iterator &iter2) {
return (*(iter1.ref->key) == *(iter2.ref->key)) ? true : false; }

我收到此错误

error: invalid use of template-name ‘cs540::Map’ without an argument list

然后我尝试了这个

template<typename Key_T, typename Mapped_T>
bool operator==(const Map<Key_T,Mapped_T>::Iterator &iter1, const Map<Key_T,Mapped_T>::Iterator &iter2) {...}

我收到此错误

error: need ‘typename’ before ‘cs540::Map<Key_T, 
Mapped_T>::Iterator’ because ‘cs540::Map<Key_T, Mapped_T>’ is a dependent scope

1 个答案:

答案 0 :(得分:3)

错误消息告诉您需要告诉编译器Map<Key_T,Mapped_T>::Iterator是一种类型,在其前面写typename - 即

template<typename Key_T, typename Mapped_T>
bool operator==(const typename Map<Key_T,Mapped_T>::Iterator &iter1,
                const typename Map<Key_T,Mapped_T>::Iterator &iter2) { ...}

有关您需要执行此操作的说明,请参阅Where and why do I have to put the "template" and "typename" keywords?

但是那也不适合你。 ::左侧的所有内容均为non-deduced context;要使操作符函数模板可用,编译器必须能够从调用中推导出模板参数,但是当模板参数仅出现在非推导的上下文中时,它不能这样做。结果是Key_TMapped_T永远无法推断,operator==永远不会被使用。

您的设计似乎与

类似
template<typename Key_T, typename Mapped_T>
class Map{
    class Iterator {
        // ...
    };
    // ...
};

通常的方法是在friend定义中定义非模板operator== Iterator,即

template<typename Key_T, typename Mapped_T>
class Map{
    class Iterator {
        // ...
        friend bool operator==(Iterator iter1, Iterator iter2) {
             return /* ... */;
        }
    };
    // ...
};

一种可能的替代方法是在Iterator之外设置Map自己的类模板:

template<typename Key_T, typename Mapped_T>
class MapIterator {
    // ...
};

template<typename Key_T, typename Mapped_T>
class Map{
    using Iterator = MapIterator<Key_T, Mapped_T>;
};

现在你可以写

template<typename Key_T, typename Mapped_T>
bool operator==(MapIterator<Key_T, Mapped_T> iter1, MapIterator<Key_T, Mapped_T> iter2) {
     return /* ... */;
}

现在可以正确推断Key_TMapped_T