【问题标题】:Operators for non-primitive boxed types非原始盒装类型的运算符
【发布时间】:2016-03-17 13:52:35
【问题描述】:

我有以下类定义:

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

编译器抱怨第三次比较

没有运算符“==”匹配这些操作数。操作数类型为:MyString == MyString

这发生在任何其他非原始拳击中(例如,MyBox&lt;float&gt; 有效,但 MyBox&lt;std::map&lt;int,int&gt; &gt; 无效。为什么会这样?

这对我来说尤其不清楚,因为在第一次和第二次比较中使用了 operator T() - 为什么不能自动为 MyString 完成?

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

【问题讨论】:

  • @LogicStuff,好东西!感谢您找到它。
  • 不过,我不太确定是否关闭。副本解释了“为什么”,但没有解释“如何解决”。
  • @SergeyA 如何修复非常明显(没有operator==,所以你必须写一个)。为什么是更有趣/更困难的问题。
  • @Barry,我同意“为什么”是更有趣的问题(例如,我不知道为什么)。但是,OP 已经直接寻求帮助:UPDATE: Is there a simple solution to this other than providing the specific operators for each non-primitive template? And what to do with MyString("a") == std::string("a")。我试图解决这个问题。
  • @RobK 它是stackoverflow.com/q/35544648/1531708,对我来说它仍然出现在“已链接”下方的左侧

标签: c++ templates c++11 boxing


【解决方案1】:

在以下 SO 问题中回答了为什么它适用于内置类型但不适用于自定义类型的原因:using user-defined conversions with implicit conversions in comparisons。简而言之,这是因为模板推导类型不会发生类型转换。虽然int 的内置operator== 不是模板(因此可以在使用MyBox&lt;int&gt; 时使用类型转换找到),但std::stringoperator== 是模板。

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

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);
}

【讨论】:

  • 你是对的,“如何解决这个问题?”可能更重要,谢谢:-)。但是:这必须为我想使用的每个操作员 (&lt;,&gt;, &lt;=, &gt;=, ==, !=, ....) 完成,对吗?我真的要写#Operators * 3免费函数,看起来都差不多吗?
  • @PhilLab,“为什么”的问题在副本中得到了回答。我回答了“如何解决这个问题”的问题,这似乎并没有在副本中得到解决。
  • 我想知道为什么我的回答被否决了。有人发现它有问题吗?
  • @juanchopanza,有道理。完成。
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
相关资源
最近更新 更多