2015-10-24 9 views
5

2つのタイプが同じかどうかチェックしたいと思いますが、テンプレートパラメータに関係なくチェックします。このような何か:2つのタイプが同じテンプレートクラスから来たかどうかをチェックする方法

template<class T> 
class A {}; 
class B {}; 

int main() { 
    cout << std::is_same_template<A<int>, A<string>>::value << endl; // true 
    cout << std::is_same_template<A<int>, B>::value << endl; // false 
} 

は、私は2つのタイプがexacty一致するかどうかをチェックするためにstd::is_sameの承知しています。私はこれを必要とする理由

理由: 私はどのようなタイプで呼び出すことができますテンプレートメソッドを持っていますが、私はそれを禁止したいと思いますが、おそらくstatic_assertを使用することにより、(テンプレートである)タイプAと呼ばれています。私が使用して、いくつかの一般的なTsのためにAを手動で除外することができ 、私が探しています:Aはテンプレートはありませんでした

EDIT ...、私はそれがstd::is_sameを使用して簡単に行うことができると考えているが、今、私は問題を抱えていますすべてのTのためにそれを行う方法:

static_assert(!std::is_same<parameter_type, A<int>>::value, "Cannot use this function with type A<T>"); 
static_assert(!std::is_same<parameter_type, A<double>>::value, "Cannot use this function with type A<T>"); 
static_assert(!std::is_same<parameter_type, A<bool>>::value, "Cannot use this function with type A<T>"); 
+0

二種類テンプレートパラメータが異なる場合、同じではありません。したがって、 'A 'と 'A 'は同じタイプではありません。 – skypjack

+2

まあ、私はよく知っているので、私は 'std :: is_same'を使うことができません。私が求めているのは、あまり厳密に比較する方法がない場合、A とA を等しく比較し、A とBを比較しないようにする方法です。 – jureslak

+0

テンプレートの特殊化によって逆のアプローチを使用できます。したがって、許可されたクラスのみを受け入れ、それ以外の場合は空の/壊れた/投げ込み/その他の関数を定義します。 – skypjack

答えて

4

わかりましたが、どのようにこのことについて:

#include <iostream> 

template<class T> 
struct A {}; 
struct B {}; 

template <typename T> 
struct should_reject { static constexpr bool value = false; }; 

template <typename T> 
struct should_reject<A<T>> { static constexpr bool value = true; }; 

template <typename T> 
void rejectA(T t) 
{ 
    std::cout << should_reject<T>::value << std::endl; 
} 

int main() { 
    rejectA(B());   // false 
    rejectA(1);   // false 
    rejectA(1.0);   // false 
    rejectA(A<B>());  // true 
    rejectA(A<int>()); // true 
    rejectA(A<double>()); // true 
} 
+0

私は、あなたの中の二人を同じように比較したいと思いますが、あなたは私にいくつかのアイデアをくれました。 cetain typdefが定義されている型を拒否するように機能するように微調整できますか?または、おそらくランタイム値...(とdownvoteは私のものではありません) – jureslak

+0

ああ、私は完全にあなたの質問を誤解しました。そのために残念。 –

+0

私は自分の答えを編集しました。 –

3

私は現在、project of mineに使用NikitaKakuevの答え、@より簡単な方法を作ってみました。

template<typename, typename> 
constexpr bool is_same_template{false}; 

template< 
    template<typename...> class T, //typename T in C++17 
    typename... A, 
    typename... B 
> 
constexpr bool is_same_template< 
    T<A...>, 
    T<B...> 
>{true}; 

現在の唯一の問題は、タイプとタイプ名が混在するテンプレートです。 std::array<int, 10>
この制限を解決するには、特殊化が必要です。

使用:

bool b = is_same_template<std::string, std::wstring>; //true 
//both are typedefs of std::basic_string 

編集:以下のコメントに@Helixによって要求されるように、std::arrayための専門(または同一の署名を有する任意の他のテンプレート):

template< 
    template<typename, std::size_t> class T, //typename T in C++17 
    typename TA, std::size_t NA, 
    typename TB, std::size_t NB 
> 
constexpr bool is_same_template< 
    T<TA, NA>, 
    T<TB, NB> 
>{true}; 
+0

ねえ、私は、その専門分野の例を含めるように答えを更新できるかどうか疑問に思っていましたか? – FrogTheFrog

+1

@Helixそこに行きます。 – bit2shift

関連する問題