2017-01-03 55 views
3

如何識別模板參數是否爲std::complex?我想要一個支持float,double,int等所有數據類型的通用方法。 我知道使用std :: is_same我可以特別檢查給定類型,例如std::complex<float>。 但在這裏我需要一個通用的方法。如何識別模板參數是否爲std :: complex?

+2

模板專業化 – Danh

+4

你想「專精」什麼?添加一個具體的例子,你的文章沒有足夠的信息來回答。 – Holt

回答

2

正如我理解你的問題,你正在尋找一種通用方法的實現來測試給定類型是否是給定模板模板類型的特化。這可以使用類模板來完成,有點像Frank's answer。我將爲您呈現互補的方式向專業化 - 模板類型別名與函數重載:

#include <type_traits> 
#include <complex> 
#include <iostream> 

template <template <class...> class TT, class... Args> 
std::true_type is_tt_impl(TT<Args...>); 
template <template <class...> class TT> 
std::false_type is_tt_impl(...); 

template <template <class...> class TT, class T> 
using is_tt = decltype(is_tt_impl<TT>(std::declval<typename std::decay<T>::type>())); 

int main() { 
    static_assert(is_tt<std::complex, std::complex<int>>::value, "!"); 
    static_assert(is_tt<std::complex, std::complex<float>>::value, "!"); 
    static_assert(!is_tt<std::complex, float>::value, "!"); 
} 

[live demo]

您可以利用特點如下:

#include <type_traits> 
#include <complex> 
#include <iostream> 

//complementary approach to specialization one would be to use function overloading 
template <template <class...> class TT, class... Args> 
std::true_type is_tt_impl(TT<Args...>); 
template <template <class...> class TT> 
std::false_type is_tt_impl(...); 

template <template <class...> class TT, class T> 
using is_tt = decltype(is_tt_impl<TT>(std::declval<typename std::decay<T>::type>())); 

template <class T> 
typename std::enable_if<is_tt<std::complex, T>::value>::type print(T t) { 
    std::cout << "(" << t.real() << "," << t.imag() << ")" << std::endl; 
} 

template <class T> 
typename std::enable_if<!is_tt<std::complex, T>::value>::type print(T t) { 
    std::cout << t << std::endl; 
} 


int main() { 
    print(std::complex<int>(1, 2)); 
    print(std::complex<double>(1.5, 2.5)); 
    print(5.5); 
} 

(1,2)
(1.5,2.5)
5.5

[live demo]

8

這可以使用部分模板專業化來完成。

首先定義一個包羅萬象的模板默認爲false:

template<typename T> 
struct is_complex_t : public std::false_type {}; 

然後你符合你條件的類型提供過載:

template<typename T> 
struct is_complex_t<std::complex<T>> : public std::true_type {}; 

我也想補充工具功能以及:

template<typename T> 
constexpr bool is_complex() { return is_complex_t<T>::value; } 

編輯:不需要此效用函數或有用與C++ 14及以上,因爲std :: integral_type實現operator()。

用法:

bool int_is_complex = is_complex<int>(); //false 
bool complex_is_complex = is_complex<std::complex<float>>(); //true 
3

您可以基於你對tag分派技術解決方案。
它遵循最小,工作示例:

#include<complex> 
#include<utility> 
#include<iostream> 

class C { 
    template<typename T> 
    void f(int, std::complex<T>) { 
     std::cout << "complex" << std::endl; 
    } 

    template<typename T> 
    void f(char, T &&t) { 
     std::cout << "something else" << std::endl; 
    } 

public: 
    template<typename T> 
    void f(T &&t) { 
     f(0, std::forward<T>(t)); 
    } 
}; 

int main() { 
    C c; 
    c.f(0); 
    c.f(std::complex<float>{}); 
} 

在這裏,你必須能夠接受幾乎所有的東西,並在內部分發到正確的函數的一般方法f

相關問題