2017-01-03 15 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<std::complex<T>> : public std::true_type {}; 

は、私はまた、ユーティリティを追加したい:

template<typename T> 
struct is_complex_t : public std::false_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

あなたがタグ派遣法上のあなたのソリューションをベースにすることができます。それは、最小限、実施例以下の
:ここ

#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を持っています。

関連する問題