2016-11-15 168 views
2

有没有办法禁用转换运算符?标记他们“=删除”弄乱其他东西。删除转换运算符

考虑下面的代码:

class Foo 
{ 
public: 

    Foo() :mValue(0) {} 
    ~Foo() = default; 
    Foo(int64_t v) { mValue = v; } 
    Foo(const Foo& src) = default; 

    bool operator==(const Foo& rhs) { return mValue == rhs.mValue; } 

    /* after commenting these lines the code will compile */ 
    operator int() const = delete; 
    operator int64_t() const = delete; 

private: 
    int64_t mValue; 
}; 

int main() 
{ 
    Foo foo1(5); 
    Foo foo2(10); 
    bool b1 = (foo1 == foo2); 
    bool b2 = (foo1 == 5); 
} 

这不能编译,因为GCC抱怨说,==操作符是不明确的:

test.cc: In function ‘int main()’: 
test.cc:25:21: error: ambiguous overload for ‘operator==’ (operand types are ‘Foo’ and ‘int’) 
    bool b2 = (foo1 == 5); 
        ^
test.cc:25:21: note: candidates are: 
test.cc:25:21: note: operator==(int, int) <built-in> 
test.cc:25:21: note: operator==(int64_t {aka long int}, int) <built-in> 
test.cc:10:10: note: bool Foo::operator==(const Foo&) 
    bool operator==(const Foo& rhs) { return mValue == rhs.mValue; } 
     ^

然而,评论的转换操作符,代码将后编译和运行很好。

第一个问题是:为什么删除的转换运算符为==运算符创建了一个模糊性?我认为他们应该禁用隐式Foo - > int转换,但它们似乎会影响int - > Foo转换,这对我来说听起来并不合逻辑。

第二个:有没有办法标记转换操作符被删除?是的,通过不声明 - 但我正在寻找一种方式,任何人在未来将看到,这些转换被设计禁用。

+0

[为什么C++ 11删除的函数参与重载解析?](http://stackoverflow.com/questions/14085620/why-do-c11-deleted-functions-participate-in-overload -解析度) – moooeeeep

回答

2

这就是我认为是问题的症结所在:

[dcl.fct.def.delete]

程序除了声明它之外,隐式地或显式地引用已删除的函数是不合格的。
...
已删除的函数隐式为内联函数([dcl.inline])。

[class.member.lookup/4]

如果C包含名称f的宣言,宣言中 包含F的用C满足在其中查找出现的语言结构的 要求宣布每声明。

即使你delete函数,你仍然声明它。并且声明的函数将参与重载解析。只有当解析的重载时,编译器才会检查它是否被删除。

在你的情况下,当这些函数声明存在时,会有明显的歧义。

3

任何使用删除的函数都是不合格的(程序不会编译 )。

如果该功能过载,首先需要重载解析, ,如果删除的功能选择了 ,程序只会生成不正确的格式。

在你的情况下PROGRAMM无法选择转换becouse你有3个变种

  • INT - >富

  • 美孚 - > INT

  • 美孚 - > Int64的

第二q题目了: 你可以离开它,因为它是,但始终使用显式转换为INT

bool b2 = (foo1 == Foo(5));