运算符在模板类外部重载,具有隐式转换

时间:2013-06-23 10:17:26

标签: c++ operator-overloading

我有一个像这样定义的模板类

template<class T> class Wrap
{
    /* ... */
public:
    Wrap(const T&);
    /* other implicit conversions */

    /* ... */
};

我想在类之外定义此类的所有比较运算符,如此

template<typename T> bool operator == (const Wrap<T>&, const Wrap<T>&)
{
    // Do comparison here
}

但是,此声明不支持将const T&或任何其他类型的隐式转换为const Wrap<T>&

所以我的问题是当其中一个操作数是Wrap<T>类型而另一个操作数不是时,我如何使它支持隐式转换。我不想为每个可能的排列编写每个运算符的多个声明。

2 个答案:

答案 0 :(得分:4)

template<class T> struct is_wrap : std::false_type {};
template<class T> struct is_wrap<Wrap<T>> : std::true_type {};

template<class T1, class T2> typename std::enable_if<is_wrap<typename std::common_type<T1, T2>::type>::value, bool>::type operator == (const T1& t1, const T2& t2)
{
    const typename std::common_type<T1, T2>::type& tc1 = t1, tc2 = t2;
    // compare with tc1 and tc2
}

答案 1 :(得分:1)

其他人会更好地表达这一点,但我认为问题在于,如果没有将T对象传递给Wrap<T>,编译器就无法在Wrap中推导operator==。我认为如果你明确地给operator==<int>(7, 4)一个模板参数,你的情况应该得到解决:template<typename T> typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const Wrap<T>& l, const T& r) { return l.stuff == Wrap<T>(r).stuff; } template<typename T> typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const T& l, const Wrap<T>& r) { return r == l; // call above operator } ,例如应该有效。

我面前没有编译器,但这是我的尝试:

Wrap

如果任何一方是const T&而另一方不是Wrap,这应该有用。您也可以将T作为operator==,但如果int真的可以从任何string隐式构建,那么您将使用{{1}}进行许多无意识的比较,即使是{{1}} {1}} s,{{1}} s等