【问题标题】:Implicit Conversion of Templated Class for Operator==()Operator==() 的模板类的隐式转换
【发布时间】:2015-11-28 20:28:49
【问题描述】:

我有一个这样的模板类:

struct Base
{
    bool operator==(const Base& other) const {
        return v == other.v;
    }
    int v;
};
struct Abc : public Base
{
    void execute() { /*logic1*/ }
};

struct Def : public Base
{
    void execute() { /*logic2*/ }
};

template <typename T>
class Foo
{
public:
    bool operator==(const Foo& other) const {
        return (a == other.a) && (b == other.b);
    }

    int a;
    T b;
};

这很好用,但是我想扩展这个 operator==() 方法以允许相等性仅在传入的对象是相同的模板类型时才有效。这是一个例子:

Foo<Abc> obj1;
Foo<Abc> obj2;
Foo<Def> obj3;

obj1 == obj2; // should be true
obj1 == obj3; // should fail at compile-time or run-time

当我这样做时:

bool operator==(const Foo& other) const {
    std::cerr << typeid(other).name() << std::endl;
    return (a == other.a) && (b == other.b);
}

我注意到传入的类的实例被隐式转换为这个类的类型。我考虑在模板化对象上包含一个成员变量来区分它们,但是不得不添加一个我觉得我不应该需要的额外变量有点烦人。有没有更好的方法来实现这种平等测试?

【问题讨论】:

  • 您的运算符只能接受Foo&lt;T&gt; 或派生类。您是否从 Foo 派生,它是否具有隐式构造函数?有什么问题。
  • “仅当传入的对象具有相同的模板类型时才允许相等性有效”。目前允许哪些其他类型是您不想要的?
  • @NeilKirk - 没有来自 Foo 的派生类。目前 operator==() 通过隐式转换适用于不同的 T 类型。我似乎只能选择完全删除 operator==() (以防止隐式转换),或者将其保留并获得隐式转换。我希望能够比较两个对象,例如 Foo 和 Foo 并且无法在编译时或运行时比较 Foo 和 Foo
  • @n.m. - 它目前允许 T 具有相同成员变量的任何其他类型,我希望禁止这样做,因为功能不同。有关更多上下文,请参阅我上面的回复。
  • 发布的代码与您的声明不符。显示一个比较 Foo&lt;int&gt;Foo&lt;double&gt; 并且编译器允许的示例。

标签: c++ templates operator-keyword implicit-conversion


【解决方案1】:

据我了解,存在从 Foo&lt;T1&gt;Foo&lt;T2&gt; 的隐式转换。

可能的解决方案是:

  1. 禁止隐式类型转换(对构造函数和强制转换运算符使用 explicit 关键字)。

  2. operator == 模板化并使用enable_if 以仅允许可能的组合:

    template <typename T1, typename = std::enable_if<std::is_same<T, T2>::value>::type>
    bool operator == (const Foo<T1>& other) const
    

【讨论】:

  • 谢谢,第二个选项看起来可行。您能否举例说明第一个选项对这个用例有何帮助?
  • 只需根据 cmets 的要求提供更多代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多