16

以下のスニペットを検討してください。

template <class T>
using identity = T;

template <class T>
void foo(identity<T>&&) {}

int main()
{
  int i{};
  foo(i);
}

iは左辺値であるためfoo、転送参照パラメーターを宣言する場合は、コンパイルする必要があります。ただし、identity<T>&&が になるとint&&、代わりにエラーが発生します。

コードは GCC 6.0.0 ( demo )でコンパイルされます。

Clang 3.7.0 ( demo ) でのコードのコンパイルに失敗し、次のエラー メッセージが表示されます。

error: no known conversion from 'int' 
to 'identity<int> &&' (aka 'int &&') for 1st argument

どちらが正しいですか?

4

2 に答える 2

7

転送参照ではありません。C++14 (n4140) 14.8.2.1/3 (強調鉱山):

...Pcv 修飾されていないテンプレート パラメーターへの右辺値参照であり、引数が左辺値である場合、型推定の代わりに「左辺値参照A」が使用されAます。

これは、転送参照がどのように機能するかを指定する標準の一部です。P関数パラメータの型である は、「への右辺値参照」型identity<T>です。identity<T>はテンプレートパラメータの型ですが、テンプレートパラメータそのものではないため、転送参照控除ルールは適用されません。

また、14.5.7/2 がエイリアス テンプレートについて何と言っているかを見ることもできます。

template-idがエイリアス テンプレートの特殊化を参照する場合、エイリアス テンプレートのtype-idのtemplate-parametersをtemplate-argumentsに 置き換えることによって取得される関連すると同等です。

したがって、置換されたエイリアスは の型と同等ですTが、14.8.2.1/3 は「... テンプレート パラメーターの型への参照」ではなく、「... テンプレート パラメーターへの参照」と読みます。

于 2015-04-24T15:16:42.533 に答える