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_typeint替换通用引用T&&T&它不会抱怨。

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

4

1 回答 1

2

编译器是对的。转发引用(1)的工作方式是,如果传递了 type 的左值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 以来,“转发参考”被接受为“通用参考”的替代术语,因为它更好地捕捉了意图。

于 2015-02-24T10:44:57.607 回答