非原始盒装类型的运算符

Operators for non-primitive boxed types

我有以下 class 定义:

template <typename T>
class MyBox {
public:
    MyBox(T value) { _value = value; }
    operator T() const { return _value;  }
private:
    T _value;
};

typedef MyBox<int> MyInt;
typedef MyBox<std::string> MyString;

当我尝试像这样在我的 typedef 上使用运算符时

bool first = MyInt(1) == MyInt(1);    // works
bool second = std::string(MyString("a")) == std::string(MyString("a"));    //works
bool third = MyString("a") == MyString("a");   // does not compile

编译器抱怨第三次比较

no operator "==" matches these operands. operand types are: MyString == MyString

任何其他非原始装箱都会发生这种情况(例如 MyBox<float> 有效但 MyBox<std::map<int,int> > 无效。为什么会这样?

我特别不清楚,因为第一次和第二次比较使用了 operator T() - 为什么 MyString 也不能自动完成?

更新:除了为每个非原始模板提供特定的运算符之外,是否有简单的解决方案? MyString("a") == std::string("a") 怎么办?

为什么它适用于内置类型,但不适用于自定义类型的原因在以下 SO 问题中得到了回答:。简而言之,这是因为模板推导类型不会发生类型转换。虽然 int 的内置 operator== 不是模板(因此可以在使用 MyBox<int> 时使用类型转换找到),operator== 用于 std::string是一个模板。

但是上面提到的问题并没有详细说明如何解决这个问题。方法如下:添加以下免费功能

template<class T>
bool operator==(const MyBox<T>& lhs, const MyBox<T>& rhs) {
    return static_cast<const T&>(lhs) == static_cast<const T&>(rhs);
}

template<class T>
bool operator==(const MyBox<T>& lhs, const T& rhs) {
    return static_cast<const T&>(lhs) == rhs;
}

template<class T>
bool operator==(const T& lhs, const MyBox<T>& rhs) {
    return lhs == static_cast<const T&>(rhs);
}