2016-03-29 39 views
1

比方說,我們有這樣一個例子類:類型轉換操作符任何算術類型,除了一些參考

class Union { 
    union Value { 
     int i; 
     float f; 
    }; 
    enum class Type { 
     Int, Float 
    }; 
    Type type; 
    Value value; 

public: 
    operator int&() { return value.i; } 
    operator float&() { return value.f; } 

    template <typename T, is_arithmetic<T>> 
    operator T() const { 
     if (type == Type::Int) 
      return static_cast<T>(value.i); 
     else 
      return static_cast<T>(value.f); 
    } 
} 

我想允許聯盟實例被強制轉換爲任何算術類型但禁止進行鑄造,除了引用有些像例子中的int和float類型。對於給定示例,編譯器會通知現有的多個轉換。如何處理這樣的問題?它甚至有可能嗎?

回答

0

我想出了像實施給運營商的解決方案:

operator int&(); 
operator float&(); 
operator T(); 
operator T() const; 

有了這套運營商的,我能夠確定的算術變量,像我一樣想到即非const,常量,const引用和額外特定類型的引用,如int和float。

1

問題是is_arithmetic<T>。它不是你所想的那樣。這是一個模板非類型參數。 is_arithmetic是一個類,一個類型。

把它看成是這樣的:

template <class T, int N> 
struct X {}; 

而且你還可以省略該參數名:

template <class T, int> 
struct X {}; 

,而不是int你有is_arithmetic<T>現在。

擺脫它和它的作品:

template <typename T> 
operator T() const { 

我的看法是,你並不需要確保T是一個算術類型,如static_cast這是否適合你。

如果要強制執行,在聲明中,你需要SFINAE和enable_if,也就是直到我們有概念:

template <class T, class Enable = std::enable_if_t<std::is_arithmetic<T>::value>> 
operator T() const { 

我也有你的設計的一些關切。作爲一個經驗法則,隱式轉換是不好的。所以你至少可以讓它們明確。

+0

我寫的is_arithmetic 的方式更像僞代碼,不會使用不必要的代碼膨脹示例。我會提出解決方案,我在答案中作出。 –

+0

但我感謝您對模板的解釋。 –