2016-11-15 172 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));