2014-02-13 76 views
0

以下代碼爲整數創建基類包裝器。它提供了一個方法value()來獲取和設置它的值,以及一個用戶定義的轉換和一個賦值操作符。解決含糊不明隱藏的模糊用戶定義轉換

派生類是一個模板(打算與枚舉一起使用),它繼承隱藏Base類的value(),用戶定義的轉換和賦值操作符的Base類包裝器,並將它們替換爲專門工作的版本與提供的模板參數(一個枚舉)。

class Base 
{ 
public: 
    Base(int e) : e_(e) {} 

    inline const int& value() const { return e_; } 
    inline void value(int e) { e_ = e; } 

    inline operator const int&() const { return value(); } 
    inline Base& operator= (int e) { value(e); return *this; } 

protected: 
    int e_; 
}; 

template< typename E > 
class Enum : public Base 
{ 
    using Base::value; 
    using Base::operator const int&; 
    using Base::operator=; 
public: 
    Enum(E e) : Base(e) {} 

    inline E value() const { return static_cast<E>(Base::value()); } 
    inline void value(E e) { Base::value(e); } 

    inline operator E() const { return static_cast<E>(Base::value()); } 
    inline Enum<E>& operator= (E e) { Base::value(e); return *this; } 
}; 

enum foo_t { 
    FOO_A, 
    FOO_B, 
    FOO_C 
}; 
typedef Enum<foo_t> Foo; 

現在讓我們來調用該代碼如下所示:

Foo e(FOO_A); 

e = FOO_B; // Ok! 
foo_t b = e; // Ok! 

// Why is this not ok? 
if (e) { 
    printf("error C2451!"); 
} 
if (e.value()) { // Ok! 
    e = FOO_C; 
} 

// Why is this not ok? 
switch (e) { 
default: 
    printf("error C2450!"); 
} 
switch (e.value()) { // Ok! 
default: 
    e = FOO_A; 
} 

如果你爲什麼在和switch語句無法編譯(Ambiguous user-defined-conversion)當我明確地隱藏在基類的用戶自定義轉換(並且不應該可以訪問if和switch語句)。同樣含糊不清的e.value()函數不會遇到這個問題。

1>test.cpp(60): error C2451: conditional expression of type 'Foo' is illegal 
1>   Ambiguous user-defined-conversion 
1>test.cpp(69): error C2450: switch expression of type 'Foo' is illegal 
1>   Ambiguous user-defined-conversion 
+0

沒有「顯式隱藏」這樣的事情。訪問控制和名稱查詢是完全獨立的,不相關的概念。 –

+0

此外,請使用自1998年以來一直存在的ISO標準C++。您似乎正在使用一些預標準方言。 –

+0

我發現[此資源](http://accu.org/index.php/journals/268)提及名稱查找和訪問控制。由此我推斷,在這種情況下,隱藏(&製作私有)基類成員不會幫助解決歧義,因爲當訪問控制尚未被調用時,歧義發生,這是正確的嗎? – MicroCode

回答

1

ref#1ref#2(我似乎無法找到標準實際上是在說這個,只是人們引用它...)

看樣子C++標準有這樣說的條件:

條件應爲整型,枚舉類型或類型,其中存在單個非顯式轉換函數爲整型或枚舉類型(12.3)。如果條件屬於類類型,則通過調用該轉換函數來轉換條件,並且在本節的其餘部分中使用轉換結果代替原始條件。積分促銷被執行。

由於有2個用戶定義轉換「可用」,即使只有1個可用,標準說這是不好的。

0

(什麼是Enum這些using報表?我不知道他們在做什麼。)

我不知道爲什麼錯誤發生的事情,但你肯定可以解決與問題if聲明中加入這樣的事情Base

inline operator bool() const { return e_ != 0; } 

至於switch,我從來沒有見過任何東西,但允許整型(這Foo不是),我懷疑編譯器是否足夠聰明,試圖自己找到cast-to-enum運算符。無論如何,我總是會打電話給value()