重载模板 sub class 的 operator== 时出现问题
Problems overloading operator== of template sub class
我在重载 operator== 时遇到问题,使用 VC++(2015) 和 g++ 5.4.0 (--std==c++14) 时出现不同的编译器错误。这是代码(这只是我真实代码库中更复杂情况的摘录):
#include <vector>
template<typename T>
struct A {
struct B {
std::vector<T> _elements;
// Internal cmp op.
bool operator==(const B &other) {
return _elements == other._elements;
}
};
std::vector<B> _entries;
};
// External cmp op.
template<typename T>
inline bool operator==(typename const A<T>::B &l, typename const A<T>::B & r) {
return l._elements == r._elements;
}
int main() {
A<int>::B b0, b1;
b0.operator==(b1); // a
operator==<int>(b0, b1); // b
b0 == b1; // c
std::vector<A<int>::B> v0, v1;
std::equal(v0.begin(), v0.end(), v1.begin()); // d
v0 == v1; // e
return 0;
}
我不添加错误消息,因为我有VC++的德文版本并且g++错误跨越多行。
VC++ 在 (e) 上给出错误。我不明白为什么,因为 vector<>::operator== 似乎在内部调用 std::equal 并且 (d) 编译正常。为什么会失败?
g++ 无法接受我的外部运算符==(),因此完全无法编译这段短代码。我不知道如何为 A::B 编写一个适用于两个编译器的外部运算符==()。
我还没试过 clang。
非常感谢。
您的程序中有两个错误:
// Internal cmp op.
bool operator==(const B &other) const {
///// <- here
return _elements == other._elements;
}
应该是 const
成员并且关键字 const
不能出现在 typename
:
后面
// External cmp op.
template<typename T>
inline bool operator==(typename A<T>::B const& lhs, typename A<T>::B const& rhs)
///// <- here -> ////
{
return lhs._elements == rhs._elements;
}
请注意 const
的放置在 C++ 中通常是相当自由的,例如你可以同时写 const typename A<T>::B & lhs
和 typename A<T>::B const& lhs
,但是你选择的形式 typename const A<T>::B & lhs
是不允许的。
另请注意,您要写成员 operator==
或非成员 operator==
,但绝不能同时写两者。在您的情况下,因为 T
is not deducible 在 typename A<T>::B
中,您必须将丑陋的 operator==<int>(b0, b1)
写到 select 非成员。
我会删除非会员模板 operator==
并添加到您的 class 模板 A<T>
非会员
bool operator==(const A &other) const {
return _entries == other._entries;
}
以便您也可以比较 A<int>
的对象。请注意,这将为 std::vector
调用标准库 operator==
,后者又会为 B
.
调用您的 operator==
我在重载 operator== 时遇到问题,使用 VC++(2015) 和 g++ 5.4.0 (--std==c++14) 时出现不同的编译器错误。这是代码(这只是我真实代码库中更复杂情况的摘录):
#include <vector>
template<typename T>
struct A {
struct B {
std::vector<T> _elements;
// Internal cmp op.
bool operator==(const B &other) {
return _elements == other._elements;
}
};
std::vector<B> _entries;
};
// External cmp op.
template<typename T>
inline bool operator==(typename const A<T>::B &l, typename const A<T>::B & r) {
return l._elements == r._elements;
}
int main() {
A<int>::B b0, b1;
b0.operator==(b1); // a
operator==<int>(b0, b1); // b
b0 == b1; // c
std::vector<A<int>::B> v0, v1;
std::equal(v0.begin(), v0.end(), v1.begin()); // d
v0 == v1; // e
return 0;
}
我不添加错误消息,因为我有VC++的德文版本并且g++错误跨越多行。
VC++ 在 (e) 上给出错误。我不明白为什么,因为 vector<>::operator== 似乎在内部调用 std::equal 并且 (d) 编译正常。为什么会失败?
g++ 无法接受我的外部运算符==(),因此完全无法编译这段短代码。我不知道如何为 A
我还没试过 clang。
非常感谢。
您的程序中有两个错误:
// Internal cmp op.
bool operator==(const B &other) const {
///// <- here
return _elements == other._elements;
}
应该是 const
成员并且关键字 const
不能出现在 typename
:
// External cmp op.
template<typename T>
inline bool operator==(typename A<T>::B const& lhs, typename A<T>::B const& rhs)
///// <- here -> ////
{
return lhs._elements == rhs._elements;
}
请注意 const
的放置在 C++ 中通常是相当自由的,例如你可以同时写 const typename A<T>::B & lhs
和 typename A<T>::B const& lhs
,但是你选择的形式 typename const A<T>::B & lhs
是不允许的。
另请注意,您要写成员 operator==
或非成员 operator==
,但绝不能同时写两者。在您的情况下,因为 T
is not deducible 在 typename A<T>::B
中,您必须将丑陋的 operator==<int>(b0, b1)
写到 select 非成员。
我会删除非会员模板 operator==
并添加到您的 class 模板 A<T>
非会员
bool operator==(const A &other) const {
return _entries == other._entries;
}
以便您也可以比较 A<int>
的对象。请注意,这将为 std::vector
调用标准库 operator==
,后者又会为 B
.
operator==