在完美转发中,std::forward用于转换命名的右值引用t1和t2未命名的右值引用.这样做的目的是什么?inner如果我们离开t1&t2作为左值,那将如何影响被调用的函数?
template <typename T1, typename T2>
void outer(T1&& t1, T2&& t2)
{
inner(std::forward<T1>(t1), std::forward<T2>(t2));
}
Run Code Online (Sandbox Code Playgroud) 我在这里看到了这一点: Move Constructor调用基类Move Constructor
有人能解释一下:
std::move和std::forward,优选用一些代码示例?如果您阅读的代码如下
auto&& var = foo();
where foo是按类型值返回的任何函数T.然后var是左值类型的左值引用T.但这意味着var什么呢?这是不是意味着,我们被允许窃取资源var?是否有任何合理的情况,您应该使用auto&&告诉读者您的代码与您在返回时unique_ptr<>告诉您拥有独占所有权时的行为?例如什么T&&时候T类型?
我只是想了解,如果有任何其他用例auto&&比模板编程中的用例; 喜欢这篇文章中的例子中所讨论的那些通用参考斯科特迈尔斯.
C++ 11提供了多种迭代容器的方法.例如:
for(auto c : container) fun(c)
Run Code Online (Sandbox Code Playgroud)
for_each(container.begin(),container.end(),fun)
Run Code Online (Sandbox Code Playgroud)
但是,建议的方法是迭代两个(或更多)相同大小的容器来完成以下操作:
for(unsigned i = 0; i < containerA.size(); ++i) {
containerA[i] = containerB[i];
}
Run Code Online (Sandbox Code Playgroud) C++ 11模式下的GCC 4.7让我定义了一个以两种不同方式获取lambda的函数:
// by value
template<class FunctorT>
void foo(FunctorT f) { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)
和:
// by r-value reference
template<class FunctorT>
void foo(FunctorT&& f) { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)
但不是:
// by reference
template<class FunctorT>
void foo(FunctorT& f) { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)
我知道我可以取消模板化函数,只需要使用std :: functions,但是foo它很小并且内联,我想给编译器提供最好的机会来内联调用它.在前两个中,如果我特别知道我正在传递lambdas,那么这对性能来说是优选的,为什么不允许将lambda传递给最后一个?
在VS2010中,std :: forward定义如下:
template<class _Ty> inline
_Ty&& forward(typename identity<_Ty>::type& _Arg)
{ // forward _Arg, given explicitly specified type parameter
return ((_Ty&&)_Arg);
}
Run Code Online (Sandbox Code Playgroud)
identity似乎仅用于禁用模板参数推断.在这种情况下故意禁用它有什么意义?
我会尽量避免在C++代码分配完全.也就是说,我只使用初始化并const尽可能地声明局部变量(即总是除了循环变量或累加器之外).
现在,我发现了一个不起作用的情况.我认为这是一般模式,但特别是在以下情况下出现:
假设我有一个程序将输入文件的内容加载到字符串中.您可以通过提供文件名(tool filename)或使用标准输入流(cat filename | tool)来调用该工具.现在,我如何初始化字符串?
以下不起作用:
bool const use_stdin = argc == 1;
std::string const input = slurp(use_stdin ? static_cast<std::istream&>(std::cin)
: std::ifstream(argv[1]));
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?因为原型slurp需要看起来如下:
std::string slurp(std::istream&);
Run Code Online (Sandbox Code Playgroud)
也就是说,我的论证是非 - const因此我不能将它绑定到临时的.似乎没有办法使用单独的变量.
目前,我使用以下解决方案:
std::string input;
if (use_stdin)
input = slurp(std::cin);
else {
std::ifstream in(argv[1]);
input = slurp(in);
}
Run Code Online (Sandbox Code Playgroud)
但这是以错误的方式揉搓我.首先,它是更多的代码(在SLOC中),但它也使用一个if而不是(这里)更逻辑的条件表达式,并且它在声明后使用我想要避免的赋值.
是否有一种避免这种间接初始化方式的好方法?这个问题可能会推广到需要改变临时对象的所有情况.难道流不是设计得不好以应对这种情况(const流没有意义,但是在临时流上工作确实有意义)?
为什么在C++标准中定义std :: function <> :: operator()是:
R operator()(ArgTypes...) const;
Run Code Online (Sandbox Code Playgroud)
并不是
R operator()(ArgTypes&&...) const;
Run Code Online (Sandbox Code Playgroud)
?
有人会认为要正确转发参数,我们需要&&然后std::forward<ArgTypes>...在转发呼叫时在函数体中使用?
我部分重新实现了std :: function来测试这个,我发现如果我使用&&,当我稍后尝试通过值将参数传递给operator()时,我从g ++中得到"无法将'xxx'左值'绑定到'xxx &&'" .我认为我对rvalue/forwarding概念有了足够的把握,但我还是不能理解这一点.我错过了什么?
除非我错了,否则它们似乎都运行得很好 - 是否有一个最佳实践理由更喜欢一个而不是另一个?
例:
struct A
{
A(){}
A(const A&){ std::cout << "A(const A&)\n"; }
A(A&&){ std::cout << "A(A&&)\n"; }
};
struct B
{
B(){}
B(const B& right) : x(right.x){ std::cout << "B(const B&)\n"; }
B(B&& right) : x(std::forward<A>(right.x)){ std::cout << "B(B&&)\n"; }
A x;
};
struct C
{
C(){}
C(const C& right) : x(right.x){ std::cout << "C(const C&)\n"; }
C(C&& right) : x(std::move(right.x)){ std::cout << "C(C&&)\n"; }
A x;
};
struct D
{
D(){}
D(const D& right) : x(right.x){ …Run Code Online (Sandbox Code Playgroud) std::forward当我将它们用作参数时,我应该使用我的函数参数std::forward_as_tuple吗?
template<class ... List>
void fn(List&& ... list){
// do I need this forward?
call_fn( forward_as_tuple( forward<List>(list)... ) );
}
Run Code Online (Sandbox Code Playgroud)
我知道它们将被存储为右值引用,但还有什么我应该考虑的吗?