1

VS 2013 は、次のコードで関数テンプレートを特殊化できないと言います。

struct W { };

template <class T>
typename T::result_type
f (const W & w, T && t) {
    return 0;
}

/* ... */
struct V { typedef int result_type; };

W w {};
V v {};
f (w, v);

で置き換えるか、ユニバーサル参照をで置き換えtypename T::result_typeても、文句はありません。intT&&T&

私の意見では、上記のコードは正しいです。これはコンパイラのバグですか、それとも何か間違っていますか?

4

1 に答える 1

2

コンパイラは正しいです。転送参照(1)が機能する方法は、 type の左辺値が渡された場合、型推論の代わりにU使用することです。あなたの場合は左辺値であるため、と推定されます。は参照型であり、ネストされた型はありません (1 つも持つことはできません)。U&UvTV&V&

転送参照を使用する場合は、常に使用std::remove_referenceして基になる型を取得する必要があります。

template <class T>
typename std::remove_reference<T>::type::result_type
f (const W & w, T && t) {
    return 0;
}

(1) CppCon 2014 以降、「転送参照」は「ユニバーサル参照」の代替用語として受け入れられました。これは、意図をよりよく捉えるためです。

于 2015-02-24T10:44:57.607 に答える