ノンタイプのテンプレートパラメータと非タイプのテンプレート引数を持つテンプレートにタイプを解体できるテンプレートを作成したいと思います。たとえばArray<5>
をtemplate<int> Array
と5
に分解しますが、どのタイプの非型テンプレートパラメータ(整数型、ポインタ、メンバーポインタなど)でも一般的に機能します。ノンタイプのテンプレートパラメータのタイプの概要
テンプレートの特殊化との最初の試み、:
template<typename T> struct foo { enum { n = 1 }; };
template<int x> struct bar { enum { n = x }; };
template<typename T, template<T> class X, T x>
struct foo< X<x> > { enum { n = x }; }; // here x must be of integral type, but that's just for testing
int main(int, char**) { return foo< bar<16> >::n; }
クラン3.1は言う:
test145.cpp:6:8: warning: class template partial specialization contains a template parameter that can not be deduced; this partial specialization will never be used
struct foo< X<x> > { enum { n = x }; };
^~~~~~~~~~~
test145.cpp:5:19: note: non-deducible template parameter 'T'
template<typename T, template<T> class X, T x>
^
1 warning generated.
第二には、関数テンプレートで、試してみてください。
template<typename T, T x>
struct box
{
static constexpr T value() { return x; }
};
template<typename T, template<T> class X, T x>
box<T, x> foo(X<x>);
template<int> struct asdf { };
int main(int, char**) { return decltype(foo(*(asdf<9>*)0))::value(); }
クラン氏は述べています:
test150.cpp:12:41: error: no matching function for call to 'foo'
int main(int, char**) { return decltype(foo(*(asdf<9>*)0))::value(); }
^~~
test150.cpp:8:11: note: candidate template ignored: couldn't infer template argument 'T'
box<T, x> foo(X<x>);
^
1 error generated.
GCC 4.7は同様のことを言います。
これは基本的な制限ですか?
ボーナスの質問:それがそうであれば、単純で汎用的なコードではなくても、有限のコードで無限の可能性をすべて処理する方法はありますか? (これは、例えばポインタでは困難で取得します:あなたは私はあなたがどちらかtemplate<T*>
を書くことができないと思うtemplate<T>
を書くように見えることはできません同じ理由で。)
私が求めている理由は聞かないでください。
私は言う必要があります:あなたが必要とするものが分かりません –
私は次のように要約することができます: 'テンプレート構造A {}'。'arg :: template_'が' template Array'であるようなテンプレート 'arg'を書くことは可能でしょうか(もしそうなら、どうすればよいでしょうか?)' arg :: type 'は' int'であり、 'arg' > :: value'は '5'(型は' int')であり、これを汎用的にして、可能なすべての非型テンプレート引数をこのように扱うことができます。 –
reima
それは基本的にそれです。私ができるよりもはっきりと置いてくれてありがとう! – glaebhoerl