Xeo*_*Xeo 9 c++ perfect-forwarding c++11
简单的问题,为什么不做以下工作(暗示副本ci)?
#include <utility>
int main(){
const int ci = 2;
std::forward<int>(ci);
}
Run Code Online (Sandbox Code Playgroud)
prog.cpp:在函数'int main()'中:
prog.cpp:6:23:错误:没有用于调用'forward(const int&)'的匹配函数
在编写一些模板内容时,问题就出现了,我有一个简单的持有者类型,如下所示.为了避免不必要的副本,我尽可能使用完美转发,但结果证明它似乎是问题的根源.
template<class T>
struct holder{
T value;
holder(T&& val)
: value(std::forward<T>(val))
{}
};
template<class T>
holder<T> hold(T&& val){
// T will be deduced as int, because literal `5` is a prvalue
// which can be bound to `int&&`
return holder<T>(std::forward<T>(val));
}
template<class T>
void foo(holder<T> const& h)
{
std::tuple<T> t; // contrived, actual function takes more parameters
std::get<0>(t) = std::forward<T>(h.value); // h.value is `const T`
}
int main(){
foo(hold(5));
}
Run Code Online (Sandbox Code Playgroud)
如果需要任何进一步的信息,请告诉我.
我们非常感谢任何想要绕过这个问题的想法.
How*_*ant 19
这个:
#include <utility>
int main(){
const int ci = 2;
std::forward<int>(ci);
}
Run Code Online (Sandbox Code Playgroud)
不起作用,因为你不能暗中抛弃const. std::forward<T>(u)应该理解为:
转发
u为T.
你试图说:
Forward an lvalue `const int` as an rvalue `int`.
Run Code Online (Sandbox Code Playgroud)
扔掉了const.为了避免丢弃,const你可以:
#include <utility>
int main(){
const int ci = 2;
std::forward<const int>(ci);
}
Run Code Online (Sandbox Code Playgroud)
其中说:
Forward an lvalue `const int` as an rvalue `const int`.
Run Code Online (Sandbox Code Playgroud)
在你的代码中:
template<class T>
void foo(holder<T> const& h)
{
std::tuple<T> t; // contrived, actual function takes more parameters
std::get<0>(t) = std::forward<T>(h.value); // h.value is `const T`
}
Run Code Online (Sandbox Code Playgroud)
在const上限定符h影响数据成员选择表达h.value. h.value是一个const左值int.您可以使用forward它将其更改为const右值int,或者您可以使用forward它来保持不变(作为const左值int).你可以甚至使用forward加volatile(虽然我不能想到一个很好的理由).
在你的例子中,我看不出任何理由forward(除非你const取消h).
std::get<0>(t) = h.value; // h.value is `const T`
Run Code Online (Sandbox Code Playgroud)
你的评论甚至还是正确的.
这是一个干燥的阅读,但N2951调查你可以做什么和不能做什么forward以及为什么.在标准化之前,N3143对此进行了修改,但在最终的N3143配方中,用例和基本原理仍然有效且未发生变化.
你可以做的事情forward:
你不能做的事情forward:
int为a double).