2015-12-06 146 views
2

我想檢查模板中提供的類型是否具有size_t類型並返回算術類型。對於int,看起來像如何檢查類型是否提供算術類型函數

template <typename U> 
struct has<U> { 
    template <typename T, T> 
    struct helper; 
    template <typename T> 
    static std::uint8_t check(helper<int (*)(size_t), &T::function_name>*); 
    template <typename T> 
    static std::uint16_t check(...); 

    static constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); 
}; 

但它對於所有算術類型看起來如何?

+0

如果您確實知道函數名稱,那麼函數沒有重載(如cv限定符,ref限定符,調用約定)是最簡單的。 –

回答

2

您可以使用現代化的黑魔法實現has_something檢查:

// Stolen from C++17 std:: 
template<typename...> using void_t = void; 

template<typename T, typename = void_t<>> 
struct has: std::integral_constant<bool, false> { 
}; 

template<typename T> 
struct has<T, void_t<decltype(T::function_name(std::declval<std::size_t>()))>>: 
    std::is_arithmetic<decltype(T::function_name(std::declval<std::size_t>()))> { 
}; 

的這裏的想法是,部分特化是更好(更專業的)時,其void_t裏面的東西是有效的。否則使用一般默認值。在這裏,我將所有T的參數分爲和size_t參數。之後,我會對該呼叫的返回類型進行額外的is_arithmetic檢查。您可能會發現此檢查有點鬆動:function_name(float)將通過它,因爲size_t值可以隱式轉換爲float。你可能會因爲知道function_name存在並且檢查它而不會觸發硬編譯錯誤而輕鬆地進行部分專業化檢查並附加檢查。

相關問題