VS 2013 无法根据模板参数使用通用引用和 return 类型专门化函数模板

VS 2013 fails to specialize function template with universal reference and return type depending on template parameter

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);

如果我用 int 替换 typename T::result_type 或者如果我用 T& 替换通用参考 T&&,它不会抱怨。

在我看来,上面的代码是正确的。这是编译器错误,还是我做错了什么?

编译器是对的。转发引用 (1) 的工作方式是,如果传递了类型 U 的左值,它们使用 U& 而不是 U 进行类型推导。由于 v 在您的情况下是一个左值,因此 T 被推断为 V&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 以来,"forwarding reference" 被接受为 "universal reference," 的替代术语,因为它更好地捕捉了意图。