为什么会出现以下错误:“'operator =='不匹配”? (带有模板的嵌套类)

时间:2018-06-25 10:39:15

标签: c++ class c++11 templates operator-overloading

给出以下代码:

template<class T>
class TemplateClass {
    T val;
public:
    TemplateClass(T val) :
            val(val) {
    }
    TemplateClass(const TemplateClass& tc) = default;
    TemplateClass& operator=(const TemplateClass& tc) = default;

    class Ele {
        T x;
    public:
        Ele(T x) :
                x(x) {
        }
        template<class S>
        friend bool operator==(const typename TemplateClass<S>::Ele& e1,
                const typename TemplateClass<S>::Ele& e2);
    };
};

template<class T>
bool operator==(const typename TemplateClass<T>::Ele& e1,
        const typename TemplateClass<T>::Ele& e2) {
    return e1.x == e2.x;
}

int main() {
    TemplateClass<int>::Ele e1(4);
    TemplateClass<int>::Ele e2(3);
    if (e1 == e2) {  // *********** error
        std::cout << "ok" << std::endl;
    }
}  

我收到以下错误:

  

与“ operator==”不匹配(操作数类型为“ TemplateClass<int>::Ele”和“ TemplateClass<int>::Ele”)

有人可以告诉我如何解决它,这是什么问题?

2 个答案:

答案 0 :(得分:2)

类型的嵌套名称属于non-deduced contexts

  

1)嵌套名称说明符(范围解析运算符::的所有内容),该类型是使用限定ID指定的:

由于模板自变量推导失败,因此无法调用operator==。模板参数无法推论。

您可以使其成为非模板函数,并在类定义中对其进行定义。例如

template<class T>
class TemplateClass {
    ...
    class Ele {
        ...
        friend bool operator==(const typename TemplateClass<T>::Ele& e1,
                               const typename TemplateClass<T>::Ele& e2) {
            return e1.x == e2.x;
        }
    };
};

LIVE

或使其成为非模板成员函数,则可以在类定义之外定义它们。例如

template<class T>
class TemplateClass {
    ...
    class Ele {
        ...
        bool operator==(const typename TemplateClass<T>::Ele& e2) const;
        bool operator!=(const typename TemplateClass<T>::Ele& e2) const;
    };
};

template<class T>
bool TemplateClass<T>::Ele::operator==(const typename TemplateClass<T>::Ele& e2) const {
    return x == e2.x;
}
template<class T>
bool TemplateClass<T>::Ele::operator!=(const typename TemplateClass<T>::Ele& e2) const {
    return ! (*this == e2);
}

LIVE

答案 1 :(得分:1)

除了此处的答案之外,您还可以使用friend injection technique来修复错误:

template<class T>
class TemplateClass {
    // ...
    class Ele {
        // ...
        friend bool operator==(const Ele& e1, const Ele& e2) {
            return e1.x == e2.x;
        }
    };
};

请注意,这里根本不需要有问题的typename TemplateClass<S>::Ele