[英]Using a class template in a function template with universal reference parameter
According to msvc, gcc and clang, the following code is illegal: 根据msvc,gcc和clang,以下代码是非法的:
template <typename T>
void f(T&& e) {
std::vector<T> v;
// do something with v and e ...
}
int main() {
int i;
f(i);
}
msvc yields msvc收益率
xmemory0(591): error C2528: 'pointer': pointer to reference is illegal
xmemory0(591):错误C2528:'指针':指向引用的指针是非法的
gcc and clang give similar sounding error messages. gcc和clang给出类似的声音错误消息。 Note that the universal reference parameter
e
is not used. 请注意,不使用通用参考参数
e
。 The compiler obviously fails to instantiate the vector v
, complaining about it being used with a reference to int
: 编译器显然无法实例化向量
v
,抱怨它与int
的引用一起使用:
note: see reference to class template instantiation
'std::vector<T,std::allocator<_Ty>>'
being compiled with注意:请参阅类模板实例化
'std::vector<T,std::allocator<_Ty>>'
的编译[ T=int &, _Ty=int & ]
But I can't see where the function template f
is instantiated with a reference to int
. 但我无法看到函数模板
f
在何处通过对int
的引用进行实例化。
Can somebody explain the compiler errors that we see here? 有人可以解释我们在这里看到的编译器错误吗?
When f
is called with an lvalue int
, T
will be deduced as int&
, so v
will be a std::vector<int&>
. 当使用左值
int
调用f
, T
将推导为int&
,因此v
将是std::vector<int&>
。 This is invalid. 这是无效的。
One way to get around this is to remove references from T
before using it: 解决此问题的一种方法是在使用之前从
T
删除引用:
template <typename T>
void f(T&& e) {
using value_type = typename std::remove_reference<T>::type;
//using value_type = std::remove_reference_t<T>; for C++14
std::vector<value_type> v;
// do something with v and e ...
}
However, if you want the function to be as generic as possible, you should use std::decay
instead of std::remove_reference
. 但是,如果您希望函数尽可能通用,则应使用
std::decay
而不是std::remove_reference
。 This will let f
work with cv-qualified types, arrays and functions. 这将使
f
与cv限定类型,数组和函数一起使用。
Scott Meyers explains in this article . Scott Meyers在本文中解释道。
If the expression initializing a universal reference is an lvalue, the universal reference becomes an lvalue reference.
如果初始化通用引用的表达式是左值,则通用引用将成为左值引用。
If the expression initializing the universal reference is an rvalue, the universal reference becomes an rvalue reference.
如果初始化通用引用的表达式是rvalue,则通用引用将成为右值引用。
In your case i
is an lvalue and so T
is deduced as int&
. 在你的情况下,
i
是一个左值,因此T
被推断为int&
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.