使用采用模板化迭代器的自由函数重载 operator==
Overloading operator== With a Free Function That Takes Templated Iterators
所以我试图创建一个比较两个迭代器的函数,但我不确定如何正确使用模板。
class
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
错误消息告诉您需要告诉编译器 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_T
和Mapped_T
永远推不出来,operator==
永远用不上
您的设计似乎与
类似
template<typename Key_T, typename Mapped_T>
class Map{
class Iterator {
// ...
};
// ...
};
通常的做法是在Iterator
定义里面定义一个非模板friend
operator==
,即
template<typename Key_T, typename Mapped_T>
class Map{
class Iterator {
// ...
friend bool operator==(Iterator iter1, Iterator iter2) {
return /* ... */;
}
};
// ...
};
一种可能的替代方法是在 Map
之外制作 Iterator
自己的 class 模板:
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_T
和 Mapped_T
现在可以正确推导。
所以我试图创建一个比较两个迭代器的函数,但我不确定如何正确使用模板。 class
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
错误消息告诉您需要告诉编译器 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_T
和Mapped_T
永远推不出来,operator==
永远用不上
您的设计似乎与
类似template<typename Key_T, typename Mapped_T>
class Map{
class Iterator {
// ...
};
// ...
};
通常的做法是在Iterator
定义里面定义一个非模板friend
operator==
,即
template<typename Key_T, typename Mapped_T>
class Map{
class Iterator {
// ...
friend bool operator==(Iterator iter1, Iterator iter2) {
return /* ... */;
}
};
// ...
};
一种可能的替代方法是在 Map
之外制作 Iterator
自己的 class 模板:
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_T
和 Mapped_T
现在可以正确推导。