Scott Meyer在这个例子中明确了右值引用和转发引用之间的区别:
Widget&& var1 = someWidget; // here, “&&” means rvalue reference (1)
auto&& var2 = var1; // here, “&&” does not mean rvalue reference (2)
template<typename T>
void f(std::vector<T>&& param); // here, “&&” means rvalue reference (3)
template<typename T>
void f(T&& param); // here, “&&”does not mean rvalue reference (4)
本质上,当我们有一个deducible 时,这种区别就会发生,因此,情况(3)明确指出我们有一个vector<...>&&
,而情况(4)中的T
将被推导出来,并(在应用参考折叠规则之后)按照“值类别”进行分类。
以下面的例子为例:,但是更复杂的模式匹配会发生什么呢?:
template <template <class...> class Tuple, class... Ts>
void f(Tuple<Ts...>&& arg)
{
}
&&
在这里是什么意思?
发布于 2016-11-26 22:00:29
在上一个示例中,arg
是一个右值引用。
转发引用是对cv未限定模板参数的右值引用
并且Tuple<Ts...>
不是模板参数。
(引用自temp.deduct.call。)
发布于 2016-11-26 22:01:16
它是一个右值引用,而不是转发引用。
确保的最简单方法是尝试传递一个左值,如果失败,则它是一个右值引用,如果不是,则是一个转发引用:
template<typename... Ts>
struct foo {};
//f function definition
int main() {
foo<int, double> bar;
f(bar); // fails! Cannot bind lvalue to rvalue reference
f(foo<int, double>{}); // ok, rvalue is passed
}
发布于 2016-11-28 07:41:43
概念转发引用不是一个标准的概念,当你看到它时,它是很有用的,但如果你想正确地理解和处理它,你必须理解引用算法。(我相信Meyer的书中也有关于这一点的章节)
转发引用的概念背后是引用算法:
让我们用一个转发引用来模拟编译器模板类型推导
template<class T>
void foo(T&&);
//...
const int i=42;
foo(i); // the compiler will defines T = const int &
// T&& = const int & && = const int &
// => the compiler instantiates void foo<const int &>(const int &);
foo(6*7);// the compiler will defines T = int
// T&& = int &&
// the compiler instantiates void foo<int>(int &&);
在这种情况下,模板foo的实例化可以产生通过左值引用接受参数的函数或接受参数右值引用的函数:转发引用是右值引用还是左值引用,这取决于模板类型推断。它的名称是这样的,因为在这种情况下,参数应该作为左值或x值传递,而这是T&& std::forward<T>(T&& a)
的工作
如果你声明一个函数有:
template<class T>
void foo(ATemplateClass<T> && a);
无论编译器为T推导出什么类型,你都会得到一个右值引用参数。
https://stackoverflow.com/questions/40819058
复制相似问题