2016-11-20 3 views
3

は、次の最小限の例を考えてみましょう:最後のテンプレートパラメータではない減点とパラメータパック:この有効なコードは?

template<typename... A, typename R> 
void f(A&&..., R(*)(A...)) {} 

void g(int, char) {} 

int main() { 
    f<int, char>(42, 'c', g); 
} 

パラメータパックAは最後のパラメータではありません。
とにかく、私はR[temp.param]/11のために関数ポインタから推測されたと考えました。この上

GCC(6.2)agrees with me

、打ち鳴らすしばらく(3.9) rejects the codeとは、それが テンプレート引数Rを推測することができなかったと述べています。

私の期待は間違っていたので、GCCはそれを受け入れるべきではない、あるいはclangの問題ですか?その言及した段落から

+0

プロトタイプが 'R(*)(A ...)、A && ...'のときはどうなりますか?私は 'clang'が正しいと思う。なぜなら、引数パックが関数ポインタを飲み込んで、' R'を推測しないからです。 – StoryTeller

+0

@StoryTeller良い点。どちらのコンパイラもコードを受け入れます。とにかくそれはまったく同じではありません。関数ポインタを動かすと ''が削除され、 'f(g、42、 'c')'として 'f'が呼び出されます。 – skypjack

+0

私はそれが問題であるかどうかはわかりません。可能であればGCCの強化だけです。 – StoryTeller

答えて

1

:クラステンプレート、変数テンプレート、またはエイリアステンプレートのテンプレート・パラメータがデフォルトテンプレート引数を持っている場合

、後続の各テンプレート・パラメータは、デフォルトの鋳型をもたなければならないのいずれか引数が指定されているか、またはテンプレートパラメータパックである必要があります。プライマリクラステンプレート、プライマリ変数テンプレート、またはエイリアステンプレートのテンプレートパラメータがテンプレートパラメータパックである場合、それは最後のテンプレートパラメータになります。 ファンクションテンプレートのテンプレートパラメータパックの後には、ファンクションテンプレートのパラメータタイプリスト([dcl.fct])からテンプレートパラメータを導き出すことができないか、またはにデフォルトの引数がある場合を除いて、別のテンプレートパラメータ([temp.deduct])デフォルトの引数を持たない控除ガイドテンプレート([temp.deduct.guide])のテンプレートパラメータは、控除ガイドテンプレートのparameter-type-listから推論できます。 [例:

template<class T1 = int, class T2> class B; // error 

// U can be neither deduced from the parameter-type-list nor specified 
template<class... T, class... U> void f() { } // error 
template<class... T, class U> void g() { } // error 

- 端例]:

void f(A&&..., R(*)(A...)) 

この場合

template<typename... A, typename R>が原因で関数テンプレートのパラメーター型リストから推定することができませんA&&...は貪欲で、ではないgを使用します。R(*)(A...)

temp.deduct.call-1のように、衒学スピーキング:

パラメータ宣言リストの最後に発生する関数パラメータパックの場合、控除はのタイプPを取って、コールの残りの各引数に対して実行されます対応する関数テンプレートのパラメータ型として、関数のパラメータパックの宣言子-idを指定します。各控除では、関数パラメータパックで展開されたテンプレートパラメータパックの後続の位置のテンプレート引数が導出されます。 関数パラメータパックが推論されないコンテキスト([temp.deduct.type])に現れると、そのパラメータパックのタイプは決して推測されません。次いで

Pは< Tを含むフォームがある場合>又は< i>は、Pの各テンプレート引数リストが対応と比較され、各引数パイ:

temp.deduct.type#9のよう引数Aの対応するテンプレート引数リストのAを返します。Pのテンプレート引数リストに最後のテンプレート引数ではないパック展開が含まれている場合、テンプレート引数リスト全体は推論されないコンテキストです。 Piはパックの拡張である場合には、円周率のパターンはA.

のテンプレート引数リストの各残りの引数と比較されていて、第三の例で見ることができるように指定することはできません。

clangは拒否すると正しくなります。

+1

関数テンプレートではなくクラステンプレートの最後の部分はありませんか?私はモバイルからそれを読んでいる、私はいくつかの困難を正しくそれに続いている、ごめんなさい。 – skypjack

+0

'14.8.2.5 [temp.deduct.type]型からのテンプレート引数を控除する' '14.8関数テンプレートの特殊化[temp.fct.spec] ' – Danh

+0

とにかく[temp.deduct.call] – Danh

関連する問題