template<typename ...Args>
可変長テンプレートです。つまり、テンプレート型のパラメーターはいくつでも指定できますが、これは既にご存知だと思います。
Args...
テンプレート コードに現れるたびに、インスタンス化の型にアンパック(「展開」) されます。あなたの例では、これはです。したがって、クラスを完全に展開すると、次の定義になります。int, bool
struct A<int, bool>
{
template <int, bool>
void f() {}
};
これは、再びテンプレート化されていることを意味します (引数は、あなたが呼び出したように、別のテンプレート宣言A<int,bool>::f()
にアンパックされます) が、今回は非型のテンプレート パラメーターで型と(それらは匿名です) を使用するため、たとえば次のようにインスタンス化できます。:int
bool
f()
a.f<1, true>();
残念ながら、g++
バグがあるようで、このコードは受け入れられませんが、コードは受け入れられます。
clang
両方のコードを受け入れます。あなたのコードでは、clang はint
およびbool
テンプレート パラメーターが省略されていても気にしないと思いますが、( とは対照的に) それらが指定されていても文句を言いませんg++
。
使用例:
指定された値を使用する場合、それらを匿名にすることはできません (明らかに)。たとえば、f()
次のように、テンプレート値を「printf」するために使用されるフォーマット文字列を指定できます。
template <Args ...values>
void f(const char *fmt) {
std::printf(fmt, values...);
}
次に、次のコード
A<int> a;
a.f<42>("The answer is %d!\n");
印刷されます:
The answer is 42!
ただし、上記の構文 (Args...
匿名の非型テンプレート パラメーターに展開される) を使用すると、テンプレート パラメーターは本質的に役に立たなくなります。
値を指定しなくても、コンパイルされ (これには驚きました!)、初期化されていないint
値が出力されます。