7

次の機能の使い方がわかりません。呼び出すときにA::fテンプレート パラメーターを省略できますが、その理由がわかりません。

template <typename... Args>
struct A
{
    template <Args...>
    void f() {}
};

int main()
{
    A<int, bool> a;
    a.f();
}

具体的に言うと、これはtemplate <Args...>どういう意味ですか? また、関数呼び出しからテンプレート パラメーターを除外できるのはなぜfですか?

4

2 に答える 2

5

template<typename ...Args>可変長テンプレートです。つまり、テンプレート型のパラメーターはいくつでも指定できますが、これは既にご存知だと思います。

Args...テンプレート コードに現れるたびに、インスタンス化の型にアンパック(「展開」) されます。あなたの例では、これはです。したがって、クラスを完全に展開すると、次の定義になります。int, bool

struct A<int, bool>
{
    template <int, bool>
    void f() {}
};

これは、再びテンプレート化されていることを意味します (引数は、あなたが呼び出したように、別のテンプレート宣言A<int,bool>::f()にアンパックされます) が、今回は非型のテンプレート パラメーターで型と(それらは匿名です) を使用するため、たとえば次のようにインスタンス化できます。:intboolf()

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値が出力されます。

于 2013-05-29T20:00:17.643 に答える
0

テンプレート引数を省略できる理由は、c++ 11 にはテンプレート引数推定template<args ...>があり、基本的に異なる型名のパックである可変個引数テンプレートであるためです。このWeb サイトでは、テンプレート引数の省略について説明しています。コンパイラーが推測できる非型テンプレート引数の推定をさらに読むことから、コンパイラーはそれらが(少なくともclangで)使用されないことを認識しており、それに基づいて推測を行っていると信じています。非型テンプレート引数の推定を読んでくださいウェブサイトの一部

于 2013-05-29T20:00:37.693 に答える