2

このコードスニペットを見てください

template<class T> 
void print(T var)
{
    std::cout << var << " ";
}
 
template<class... Args> 
void Variadic(Args... args)
{
    print(args...);
}

int main()
{
     Variadic();
}

コンパイルすると、次のように表示されます。

候補: テンプレート void print(T)

候補は 1 つの引数を期待していますが、0 が提供されました

そして彼は正しい。実際、パラメーター パックでは引数を指定しませんでした。

しかし、では、なぜこのコードはコンパイルされるのでしょうか?

template<class T> 
void print(T var)
{
    std::cout << var << " ";
}
 
template<class... Args> 
void Variadic(Args... args)
{
    auto x = {0, (print(args), 0)...};
}

int main()
{
     Variadic();
}

最初に行うことは、最初の 0 をinitializer_list<>にプッシュすることです

では、先に進みましょう: コンパイラは

(print(args), 0)...

print() を呼び出そうとします… ああ、待って… Parameter Packは空で、print() 関数は 1 つのパラメーターを取ります。

では、なぜ と評価されるauto x = {0};のでしょうか?

コンパイラが以前とまったく同じエラーを表示しないのはなぜですか?

4

2 に答える 2

5

...展開演算子の仕組みを誤解しています。あなたの例でargsは、 が空のパックである場合(print(args), 0)...、 ではなく、何も展開されませんprint()

argsが与えられた場合x、 に展開されprint(x), 0ます。

argsが与えられた場合x, y、 に展開され(print(x), 0), (print(y), 0)ます。

基本的に、ビット自体argsだけでなく、含まれているすべての式を展開し、適用されます。args

標準 [temp.variadic] から:

  1. パック展開は、パターンと省略記号で構成され、そのインスタンス化により、リスト内のパターンのゼロ個以上のインスタンス化が生成されます。パターンの形式は、展開が発生するコンテキストによって異なります。

...

  1. sizeof... 式でも fold-expression でもないパック展開をインスタンス化すると、リスト E1, E2, ..., EN が生成されます。ここで、N はパック展開パラメーターの要素数です。 各 Ei は、パターンをインスタンス化し、各パック展開パラメーターをその i 番目の要素に置き換えることによって生成されます
于 2016-06-23T15:40:14.330 に答える