10

次のコードはgcc-4.7.1でコンパイルされます。

struct X {};

template <class T = X, typename U>
void f(const U& m) {
}


int main() {
    f<>(0);
}

ただし、これはそうではありません。

struct X {};

template <class T = X, typename U>
void f(const U& m) {
    auto g = [] () {};
}


int main() {
    f<>(0);
}

gcc-4.7.1の文句:

c.cpp: In function 'void f(const U&)':
c.cpp:5:15: error: no default argument for 'U'

だから私の質問は:関数テンプレートでデフォルト以外のパラメータの前にデフォルトのパラメータを置くことは正しいですか?はいの場合、2番目のものがコンパイルされないのはなぜですか?いいえの場合、なぜ最初のものがコンパイルされるのですか?C ++ 11標準はこの構文についてどのように述べていますか?

4

1 に答える 1

11

クラスとエイリアスは明示的に禁止されています。n3290§14.1.11は次のように述べています。

クラステンプレートまたはエイリアステンプレートのtemplate-parameterにデフォルトのtemplate-argumentがある場合、後続の各template-parameterには、デフォルトのtemplate-argumentが提供されるか、テンプレートパラメーターパックである必要があります。

関数の場合、唯一の制限はパラメータパックに関連しているようです。

関数テンプレートのテンプレートパラメータパックの後に、そのテンプレートパラメータを推定できるか、デフォルトの引数がない限り、別のテンプレートパラメータを続けてはなりません。

しかし、明らかにそれはこの場合には関係ありません。

§14の何も機能のためにそれを禁止していないことを考えると、それが許可されていると仮定しなければならないようです。

ワーキンググループの報告からのメモは、これが意図であることを確認しているようです。そのセクションの最初に提案された文言は次のとおりです。

クラステンプレートのtemplate-parameterにデフォルトのtemplate-argumentがある場合、後続のすべてのtemplate-parametersにはデフォルトのtemplate-argumentが指定されます。[注:テンプレートの引数が推測される可能性があるため、これは関数テンプレートの要件ではありません(14.8.2 [temp.deduct])。]

しかし、そのメモが最終バージョンのどこにあるのかわかりません。

于 2012-07-27T09:27:19.507 に答える