C++ c++;:关于转发参考的困惑
我读了Scott Meyers写的关于C++11中转发引用的文章(写得非常好) 现在,请关注本文的这一部分: 因此(使用与前一示例相同的逻辑),C++ c++;:关于转发参考的困惑,c++,c++11,move,move-semantics,forwarding-reference,C++,C++11,Move,Move Semantics,Forwarding Reference,我读了Scott Meyers写的关于C++11中转发引用的文章(写得非常好) 现在,请关注本文的这一部分: 因此(使用与前一示例相同的逻辑),&&表示转发引用 但是如果我尝试打这个电话: typedef vector<double> vecD; vecD vec; mem.callFunction<vecD, vecD>(sortFunc, vec); 因此,首先,请使用“转发参考”而不是“通用参考”。它更好地代表了它是什么以及它的预期用途是什么 首先要注意的是,并非
&&
表示转发引用
但是如果我尝试打这个电话:
typedef vector<double> vecD;
vecD vec;
mem.callFunction<vecD, vecD>(sortFunc, vec);
因此,首先,请使用“转发参考”而不是“通用参考”。它更好地代表了它是什么以及它的预期用途是什么 首先要注意的是,并非每个
&&
都是转发引用。它也可以是右值引用
简单来说,T&
是转发引用,当且仅当:
是一种简单(如下所示)类型(例如T
或vector&
不是转发引用)vector&&
- 并推导出
T
Args
。这是因为在调用函数模板参数时显式指定了函数模板参数Args
:
mem.callFunction<vecD, vecD>(sortFunc, vec);
^~~~
在第一种情况下,T
将被推断为X&
,通过折叠规则:X&&&
将变成X&
,因此我们有一个左值引用。如你所料
在第二种情况下,T
将被推断为X
,通过折叠规则X&
将成为X&
,因此我们有一个右值参考
但当你这样称呼它时:
foo<X>(x);
foo(x);
T
不再推导。你基本上说让T
beX
。因此,如果T
是X
,那么T&&
是X&
,并且您有一个错误:p
,其类型现在是X&
,无法绑定到左值
霍尔特还补充说:
还请注意,由于sortFunc的声明,这不会 即使未指定函数模板参数也可以工作 明确地说
我倾向于同意他的观点,但我需要进一步调查以确定这一点。通用参考从一开始就是一个糟糕的术语,现在它最终被更合适的转发参考所取代。你确定在你的电话中确实推断出了
Args
?请提供一个答案。提供的代码不完整(什么是sort\u vec
?),当然也不是最小的。@bolov他们几乎只是想看看相关的代码@每个人都是对的:1。您的代码片段中缺少一些部分,2。你的代码包含很多与你的问题无关的东西,3。这些与你的问题完全无关,4。代码可以是最小的,并且可以为编译器工作。对于您的问题来说,这可能是一个很好的MCVE,它有25行长。还要注意,由于sortFunc
的声明,即使您没有明确指定函数模板参数,这也不起作用。我想我理解您的答案,但我的下一个问题是:有一种方法可以使我的代码“转发可引用”(并因此使Args
类型推断)?@justHelloWorld乍一看我会说不(至少不是没有一些讨厌的丑陋的黑客)。你需要为sortFunc
指定Args
。也许如果你使memFunc
成为最后一个参数(不知道是否可能)因此,先进行Args
推断,然后它会更改memFunc
的签名。但是你可以在memFuc
的参数签名中添加remove\u reference\t
。正如我所说,丑陋的黑客行为。@justHelloWorld如果你把它作为一个单独的问题发布的话(但请尽量少用)有人会想出一个好的解决方案。打开此主题的问题:
#include <functional>
#include <vector>
using namespace std;
struct MultiMemoizator {
template <typename ReturnType, typename... Args>
ReturnType callFunction(std::function<ReturnType(Args...)> memFunc, Args&&... args) {
}
};
typedef vector<double> vecD;
vecD sort_vec (vecD const& vec) {
return vec;
}
int main()
{
vecD vec;
std::function<vecD(vecD)> sortFunc(sort_vec);
MultiMemoizator mem;
mem.callFunction<vecD, vecD>(sortFunc, vec);
}
mem.callFunction<vecD, vecD>(sortFunc, vec);
^~~~
struct X {};
template <class T>
auto foo(T&& p) {}
X x;
foo(x);
foo(X{});
foo<X>(x);