2016-05-06 24 views
2

現在、テンプレートを持つ型の特定の実装が必要なコードを作成しています。したがって、テンプレート型の型の型を記述しようとしています。定数の値を持つ任意のテンプレート型の型の型

は今のところ、私はこれを持っている:

template<class T> 
struct TIsTemplated { enum { Value = 0 }; }; 

template<template<typename, typename...> class T, typename First, typename... Values> 
struct TIsTemplated<T<First, Values...>> { enum { Value = 1 }; }; 

これは、それは、すぐに一定の値を持つタイプがあるようしかし失敗

template<typename T> 
struct X { }; 

のようなテンプレートの種類に適しています:

template<typename T, int i = 10> 
struct Y {}; 

私は次のようなタイプを作ることができました:

template<int A, template<typename, int> class T, typename First> 
struct TIsTemplated<T<First,A>> { enum { Value = 1 }; }; 

しかし、これは、私がintを取るタイプを持っていることがわかっている場合にのみ機能します。私はこれを一般化しようとしました:

template<typename C> 
template<C A, template<typename, C> class T, typename First> 
struct TIsTemplated<T<First,A>> { enum { Value = 1 }; }; 

これは正しくコンパイルにもかかわらずしかし、TIsTemplatedはまだタイプYためfalseです。定数型を知らなくてもこれを達成する方法はありますか?

+0

なぜあなたはこれを行う必要があると思うのですか?これは、「その現在の特性にかかわらず、それぞれの国の南半球で製造されたすべてのレンガを特定する必要がある」と言います。 – Yakk

+1

私はC++から別の言語にいくつかのバインディングを生成しています。ほとんどの型は一般化された実装を使用できますが、テンプレート型は各型の実装が必要です。私は何とかC++コンパイラにこれらのケースでデフォルトの実装を使わないように指示する方法を見つける必要があります。コンテキストの場合、プロジェクトはhttps://github.com/proletariatgames/unreal.hxであり、テンプレートは現在動作していますが、私はそれらをどのように処理してグルーコードガーベッジを少なくすることができるか再考しています – Waneck

+1

なぜ実装が必要なのですか?それぞれのタイプ?テンプレートをバインドする場合、それは1つのことですが、テンプレートによって生成された型をバインドする場合、それは前記テンプレートによって生成されるすべての型をバインドすることを意味するのはなぜですか?テンプレートによって生成される型は実装の詳細です。第二に、包む必要があるテンプレートの有限リストがありますか?与えられたテンプレート(または「テンプレートパターン」)をヘドローンテンプレートパラメータ「種類」で比較的簡単にラップし、型だけを取るようにして、型のみのテンプレート問題を解決することができます。 – Yakk

答えて

1
template<class...>struct types{using type=types;}; 

は種類のバンドルです。

template<class Scalar, class T> 
struct is_template_with_scalar : std::false_type {}; 

template<class Scalar, template<class,Scalar>class Z, class U, Scalar s> 
struct is_template_with_scalar<Scalar, Z<U,s>> : std::true_type {}; 

タイプTパターンtemplate<class, Scalar>と一致しない、Scalarタイプ与えられたテストです。

我々はそれを少しカレー:

template<class Scalar> 
struct scalar_test { 
    template<class T> 
    using result=is_template_with_scalar<Scalar, T>; 
}; 

これはブールタイプの束を取り、彼らの論理的あるいは評価:

template<class...Ts> 
struct or_types : std::false_type {}; 

template<class T0, class...Ts> 
struct or_types<T0, Ts...> : std::integral_constant<bool, T0{} || or_types<Ts...>{} > 
{}; 

passes_anyはタイプのリストを取得し、メタ - 型を取るテスト。

template<class List, template<class>class Test> 
struct passes_any {}; 

template<class...Ts, template<class>class Test> 
struct passes_any<types<Ts...>, Test> { 
    template<class U> 
    using result=or_types< typename Test<Ts>::template result<U>... >; 
}; 

今、私たちはで始まる:それはテストのいずれかが渡された場合を述べてテスト生成

using scalars_supported = types<int, char, std::size_t, unsigned>; // etc 

をそして、我々はテストを得る:

template<class T> 
using is_scalar_template = 
    typename passes_any<scalars_supported,scalar_test>::template result<T>; 

与えられましたタイプTは、scalars_supportedリスト内の任意のScalarのパターン<class, Scalar>を持つテンプレートのインスタンスであれば、真実タイプです。

live example

+0

十分にありがとうございます!その実装は素晴らしいです! – Waneck

関連する問題