2013-02-13 32 views
0

我有一個類型序列,我想可以自由轉換到另一個。請看下面的玩具例子:相互轉換類型和模糊調用

struct A { 
    int value; 
    A(int v) : value(v) { } 
}; 

struct B { 
    int value; 
    B(int v) : value(v) { } 
    B(A a) : value(a.value) { } 
    operator A() const { return A(value); } 
}; 

struct C { 
    int value; 
    C(int v) : value(v) { } 
    C(A a) : value(a.value) { } 
    C(B b) : value(b.value) { } 
    operator B() const { return B(value); } 
    operator A() const { return A(B(*this)); } // <-- ambiguous 
}; 

int main(int argc, const char** argv) { 
    C c(5); 
    A a(3); 
    a = c; 
} 

所以你看,我試圖定義每個後續類型爲使用鑄鐵構造以前所有類型的轉換,並且可以轉換爲使用轉換操作符以前的所有類型。唉,這並不工作打算,作爲C::operator A的定義是根據曖昧與gcc 4.7:

In member function ‘C::operator A() const’: 
19:40: error: call of overloaded ‘B(const C&)’ is ambiguous 
19:40: note: candidates are: 
9:3: note: B::B(A) 
6:8: note: constexpr B::B(const B&) 
6:8: note: constexpr B::B(B&&) 

改變表達static_cast<A>(static_cast<B>(*this))不會改變任何事情。刪除該行完全導致main中的錯誤消息,因爲沒有隱式轉換序列可能會使用多個用戶定義的轉換。在我的玩具示例中,我可以直接執行從CA的轉換,但在我的現實生活應用程序中,這樣做會導致大量重複的代碼,所以我真的很喜歡使用其他轉換運算符的解決方案。

那麼如何獲得一組三個可自由互換的類型而不需要重複轉換代碼呢?

+0

由於所有的類型都是類,你不該」 t真的需要在每個轉換構造函數和轉換運算符。如果你只是在所有類中提供轉換構造函數,它應該有助於解決模糊問題。 – Angew 2013-02-13 13:48:09

+0

@Angew,轉換構造函數的問題僅在於很難委派它們。在Java中,構造函數可以使用'this(...)'委託給另一個構造函數,但我不知道C++的這種機制。所以每個施工人員都必須自己完成所有的工作。 – MvG 2013-02-13 13:54:07

+1

@MvG:C++ 11支持委託構造函數:http://www.nullptr.me/2012/01/17/c11-delegating-constructors/#.URud1lpp6G4 – 2013-02-13 14:06:28

回答

1

我會嘗試在結構C這個辦法:

operator A() const { return this->operator B(); } 
+0

讓隱式轉換處理第二步看起來是一個縮短事情的好方法。由於'this->'也是可選的,轉換可以很快寫入。 – MvG 2013-02-13 13:57:54

1

試試這個:

operator A() const { return A(B(value)); } 

或本:

operator A() const { return A(operator B()); } 
+0

前者代表代碼重複,因爲它包含我在'C :: operator B()'中使用的代碼。但後者在我的玩具例子中很好地工作。 – MvG 2013-02-13 13:54:44