2014-10-17 57 views
8

的想法是,我有做一些事情算法對輸入的功能,也許是這樣的:如何使is_arithmetic <myClass> ::值爲真?

#include <type_traits> 
#include <vector> 

using namespace std; 

template<typename T> 
double mean(const vector<T>& vec) 
{ 
    static_assert(is_arithmetic<T>::value, "Arithmetic not possible on this type"); 
    //compute mean (average) 
}//mean 

這個偉大的工程,並計算爲我把所有的數字類型的意思,但讓。且說我創建一個新類:

class foo 
{ 
    // class that has arithmetic operations created 
};// foo 

而在這個類的定義,我定義所需的運營商,+和/,所以他們預計投入工作。現在我想用我的新類的平均函數,但顯然不會因爲static_assert而編譯。那麼如何告訴編譯器我的新類應該滿足is_arithmetic<foo>::value

這將是偉大的,如果當我創建類我可以給它一個類型,滿足is_arithmetic,但這似乎可能會導致type_traits問題莫名其妙?

或者我需要創建一個新的測試,檢查,看看

is_arithmetic<T>::value || type(T,foo) 

或類似的東西?

我寧願只需要適應我的類,而不是函數,如果可能的話,但我很好奇的解決方案。

+0

您需要編寫自己的特質。 – 2014-10-17 22:13:59

+0

@ T.C。好吧,我也這麼想。這是否很簡單,像'is_like_number'一樣創建一個新的'struct',並通過模板規範爲'foo'聲明它爲真? 沒關係,你在下面回答。謝謝 – user2386276 2014-10-17 22:21:04

回答

17

除了一個例外(std::common_type)之外,標準庫類型特徵(例如std::is_arithmetic)是「石頭」。嘗試專門化它們會導致未定義的行爲。 is_arithmetic測試該類型是否爲標準定義的算術類型;用戶定義的類型不是算術類型。

你可以寫你自己的特質,對於支持測試的算術運算符:

template<class...> struct voidify { using type = void; }; 
template<class... Ts> using void_t = typename voidify<Ts...>::type; 

template<class T, class = void> 
struct supports_arithmetic_operations : std::false_type {}; 

template<class T> 
struct supports_arithmetic_operations<T, 
      void_t<decltype(std::declval<T>() + std::declval<T>()), 
        decltype(std::declval<T>() - std::declval<T>()), 
        decltype(std::declval<T>() * std::declval<T>()), 
        decltype(std::declval<T>()/std::declval<T>())>> 
     : std::true_type {}; 

部分特將只匹配,如果都能很好地形成四個表達式(即,T支持運營商+, -, *, /)。

Demo

+1

哇,這是一個很酷的SFINAE技巧。 – leemes 2014-10-17 22:39:18

+0

雖然很酷(真的),但在Visual Studio 2013中不會失敗...... :(任何想法? – xtofl 2015-06-02 11:16:33

+0

@xtofl VC++不支持表達式SFINAE,這取決於它。 – 2015-06-02 16:16:27

2

std::is_arithmetic<T>::value是根據定義僅true如果T是在C++標準,這是整型或浮點型,這反過來又僅是基本類型的術語算術類型:

類型boolcharchar16_tchar32_twchar_t,並且有符號和無符號整數類型統稱爲整數類型

有三種浮點類型:floatdoublelong double

相關問題