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
替换为 int
或者如果我将通用引用 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 以来,“转发引用”被接受为“通用引用”的替代术语,因为它更好地捕捉了意图。
关于c++ - VS 2013 无法根据模板参数专门化具有通用引用和返回类型的函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28693563/