我必须存储参数(参数包),并将参数传递给另一个函数
结果,我不能使用lambda。一个很好的选择是std :: bind。
但对于这段代码
struct A{};
void test(A &&){}
int main()
{
A a;
test(move(a)); //work
bind(test,a)(); //compile fail; copy a to std::bind, pass a to test
}
根据标准,存储在std :: bind中的所有变量都将作为lvalue传递给函数。 (C ++标准并没有说,我认为这就是它的意思。)
这意味着我不能使用std :: bind的函数(在参数中有rvalue引用)。
一种解决方案是将test(A &&)
更改为test(A &)
,但这仅适用于您的项目(并且使其变得奇怪,而您不仅需要通过std :: thread调用test而且还需要通过plain调用test顺序呼叫)。
那么,有什么方法可以解决这个问题吗?
答案 0 :(得分:1)
您可以创建可转换为右值引用的包装器(如reference_wrapper
/ l-values引用)并将其与bind
一起使用:
它看起来像那样:
#include <iostream>
#include <functional>
struct A{};
void test(A &&){ std::cout << "Works!\n"; }
template <typename T>
struct rvalue_holder
{
T value;
explicit rvalue_holder(T&& arg): value(arg) {}
operator T&&()
{
return std::move(value);
}
};
template <typename T>
rvalue_holder<T> rval(T && val)
{
return rvalue_holder<T>(std::move(val));
}
int main()
{
A a;
test(std::move(a)); //work
auto foo = std::bind(test, rval(std::move(a))); //works
foo();
}
http://coliru.stacked-crooked.com/a/56220bc89a32c860
注意:rvalue_holder
和rval
都需要进一步努力,以确保所有情况下的效率,稳健性和理想的行为。