C++ - std::绑定调用运算符()与完美的转发
C++ - std::bind call operator() with perfect forwarding
我必须存储参数(参数包),并将参数传递给另一个函数。
因此,我无法使用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 中的所有变量都将作为左值传递给函数。(C++标准没有这么说,我认为这就是它的意思。
这意味着我不能将函数(参数中有右值引用)与 std::bind 一起使用。
一种解决方案是将test(A &&)
更改为test(A &)
,但这仅适用于您的项目(并且当您不仅需要通过 std::thread 调用 test 而且还需要通过普通顺序调用调用 test 时,这很奇怪)。
那么,有没有办法解决这个问题呢?
您可以创建可转换为右值引用(如 reference_wrapper
/l 值引用)的包装器,并将其与 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
都需要进一步的工作,以确保在所有情况下的效率、稳健性和所需的行为。
相关文章:
- 将函数参数完美转发到函数指针:按值传递呢?
- C++20理念:要求表达和完美转发
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 返回值的完美转发?
- 使用衰减与完美转发
- 可变参数模板:将整数参数完美转发到 lambda
- 完美转发C++重载和模板化函子及其参数
- 在完美转发中需要衰减
- C++完美转发:如何避免悬空引用
- 无法理解一段具有完美转发和省略号的C++代码
- 在编写包装现有函数并检查错误的模板函数时,如何使用完美转发?
- 完美转发可变参数模板模板
- 在完美转发函数中公开参数类型,避免代码重复
- 使用完美转发的模板转换构造函数
- 完美转发使用结构化绑定声明的变量
- 完美转发常量参数以进行持续评估
- 使用auto&&完美转发返回值
- 完美转发可变参数模板参数到成员函数
- 无需使用 ODR 即可实现完美转发
- 使用模板类完美转发