3

テンプレート関数をテンプレート引数として渡す方法を知っているので、同様の方法で変数テンプレートを渡すのに苦労しています。

ここに私が試したものの最小限の例があります:

#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
}

デモ

コンパイルされた場合、出力が間違っているのはなぜですか?

4

2 に答える 2

3

コードの主な問題は、ラムダが転送参照を使用して引数を受け入れるため、引数を 参照 ( )decltypeとして推測することです。裸のタイプでうまく機能します。rvalueint&&std::is_fundamental

特定のスニペットの場合、正しい解決策は参照を削除することです

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

今では動作します。:-) Coliru でライブを見る


より一般的な方法は、cv修飾子を追加で削除することです。最後に、使用したい場合がありますstd::decay

#define PASS_VARIABLE_TEMPLATE(name) [dummy=nullptr](auto&&...args) \
{return name<std::decay_t<decltype(args)>...>;}
于 2016-10-09T15:58:50.047 に答える