2016-10-09 13 views
3

私はpass template function as template argumentの方法を知っていたので、今でも同様の方法で可変テンプレートを渡すのに苦労しています。ここで変数テンプレートをλに通して渡すことは可能ですか?

は、私が試したものの最小限の例です。

#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \ 
                {return name<decltype(args)...>;} 

//testing 
template <typename T> 
bool value = std::is_fundamental<T>::value; 

template <typename Hax> 
void print_bool(Hax h) 
{ 
    std::cout << h(int{}) << std::endl; // no error, wrong output 
    //std::cout << h(int{}, float{}) << std::endl; // error, good 
} 

int main() 
{ 
    print_bool(PASS_VARIABLE_TEMPLATE(value)); //prints 0 instead of 1 
} 

Demo

それがコンパイルした場合、なぜ出力が間違っていますか?

+0

リファレンスは十分ですか? – lorro

+0

@lorroああ愚かな私は、腐敗を忘れてしまった!しかし、他の手では、参照/ポインタチェックを破壊するでしょう...この場合もチェックすることが可能でなければなりません: 'int b; int&ref = a; h(ref); //タイプはintです& 'あなたは 'の#define PASS_VARIABLE_TEMPLATE(名)[=ダミーnullptr](オート&&引数)と期待される結果が得られます – xinaiz

+0

\t { \t \tリターン名 ::タイプ>; \t} ' –

答えて

1
template<class T>struct tag_t{using type=T; constexpr tag_t(){}}; 
template<class Tag>using tagged_type=typename Tag::type; 
template<class T>constexpr tag_t<T> tag{}; 

これらのヘルプは、型を値として渡して解凍します。 print_boolインサイド

#define PASS_VARIABLE_TEMPLATE(name) [](auto...args) \ 
               {return name<tagged_type<decltype(args)>...>;} 

あなたが実行します。

std::cout << h(tag<int>) << std::endl; 

わからないあなたはdummy=nullptrことを行う理由。

tagは、テンプレートとして分類されていません。

+3

'dummy'は非捕捉ラムダのGCCバグによるものです(質問に投稿したリンクから受け入れられた答えをチェックしてください)。 Btw、素晴らしい解決策。 – xinaiz

3

コードの主な問題は、あなたのラムダ引数を受け入れるように転送参照を使用するためdecltypervalue基準(int&&)として引数を推定することです。 std::is_fundamentalは、ベアタイプでうまく動作します。

具体的なスニペットについては、正しい解決方法はremove the referenceです。

#define PASS_VARIABLE_TEMPLATE(name) \ 
    [dummy=nullptr](auto&&...args){return name<std::remove_reference_t<decltype(args)>...>;} 

これで機能します。 :-) Live On Coliru


Aもう少しまたはより良い一般的な方法は、さらにremove cv修飾子になり、それを参照してください。最後に、あなたは使いたいかもしれないstd::decay

#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \ 
{return name<std::decay_t<decltype(args)>...>;} 
関連する問題