重载模板 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;
}

Live Example

请注意 const 的放置在 C++ 中通常是相当自由的,例如你可以同时写 const typename A<T>::B & lhstypename A<T>::B const& lhs,但是你选择的形式 typename const A<T>::B & lhs 是不允许的。

另请注意,您要写成员 operator== 或非成员 operator==,但绝不能同时写两者。在您的情况下,因为 T is not deducibletypename 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==