C++初始化 std::function 时如何将占位符绑定到引用/引用参数?
C++ how can we bind a placeholder to a reference/ref argument when initializing a std::function?
#include <functional>
#include <string>
int fn( int a, int & b ) { return a+b; }
struct Fn_struct {
std::string name {};
// std::function<int (int,int&)> my_fn {};
std::function<decltype(fn)> my_fn {};
};
int main()
{
Fn_struct my_fn_struct1 {"fn(a,b)", std::function<decltype (fn)> {fn} };
Fn_struct my_fn_struct2 {"fn(a,b)", {fn} };
Fn_struct my_fn_struct3 {"fn(a,b)", {std::bind( fn, 1, 2) }};
auto fn_b = std::bind( fn, 1, std::placeholders::_1 );
Fn_struct my_fn_struct4 {"fn(a,b)", {std::bind( fn, 1, std::placeholders::_1) }}; // todo: why can't int b be a reference?
}
my_fn_struct4不编译,由于失败,找不到绑定的构造函数。 但是,如果 b 不是引用,它会编译。
另一方面,fn_b确实可以编译。
任何解释将不胜感激。
请不要问我为什么要这样做。 除非完全必要,否则我宁愿不使用指针来完成此操作。
std::bind( fn, 1, std::placeholders::_1 )
返回一个可转换为std::function<int(int &)> my_fn{};
的对象,因为传递了一个具有 2 个参数的函数,并且第一个参数绑定到 1:
#include <functional>
#include <string>
int fn( int a, int & b ) { return a+b; }
struct Fn_struct {
std::string name {};
std::function<int(int &)> my_fn{};
};
int main()
{
Fn_struct my_fn_struct4 {"fn(a,b)", {std::bind( fn, 1, std::placeholders::_1) }};
}
该行
Fn_struct my_fn_struct3 {"fn(a,b)", {std::bind( fn, 1, 2) }};
工作是因为
如果在调用 g(( 时提供的某些参数不是 与存储在 G 中的任何占位符匹配,未使用的参数为 评估并丢弃。
https://en.cppreference.com/w/cpp/utility/functional/bind
std::placeholders::_*
通过完美地转发后来取代它们的类型来工作。
因此,对于std::function<int(int, int&)>
,std::placeholders::_1
将是一个 r 值引用,不能绑定到左值引用。
您可以使用 IMO 更清晰的 lambda(即使不清楚您想要什么(:
Fn_struct my_fn_struct3 {"fn(a,b)",
[](int/*ignored*/, int&/*ignored*/){ int b = 2; return fn(1, b); }};
Fn_struct my_fn_struct4 {"fn(a,b)",
[](int a, int&/*ignored*/){ return fn(1, a); }};
演示
注意:lambda 需要额外的变量才能2
。
恕我直言,因为别名 arg. 是 2 种访问方式,因此编译器无法和/或阻止在没有永久引用的情况下初始化参数赋值。
然后它认为这是有道理的,如果参数被const
限定,它将接受并工作
#include <functional>
using namespace std;
int fn( int a, const int & b ) { // const qualifier
return a+b; }
struct Fn_struct {
string name {};
// function<int (int,int&)> my_fn {};
function<decltype(fn)> my_fn {};
};
int main()
{
Fn_struct my_fn_struct1 {"fn(a,b)", function<decltype (fn)> {fn} };
Fn_struct my_fn_struct2 {"fn(a,b)", {fn} };
Fn_struct my_fn_struct3 {"fn(a,b)", {bind( fn, 1, 2) }};
auto fn_b = bind( fn, 1, placeholders::_1 );
// obj names edited
Fn_struct my_fn_struct4 {"fn(a,b)", {fn_b} };
Fn_struct my_fn_struct5 {"fn(a,b)", {bind( fn, 1, placeholders::_1) }};
}
相关文章:
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 将常量指针引用绑定到非常量指针
- 运行时错误:引用绑定到类型为"int"的空指针
- 模板允许左值与右值引用绑定
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 无法将类型"T&"的非常量左值引用绑定到类型"T"的右值 t++ std::atomic<T>
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 将引用绑定到指针的语法是什么?(各种)
- 为什么我不能将常量左值引用绑定到返回 T&&&的函数?
- 为什么 VS 无法将右值引用绑定到指针?
- 出于什么原因,有必要将常量左值引用绑定到右值?
- 为什么此右值引用绑定到左值?
- 使用“void*”将右值引用绑定到左值
- 排序时引用绑定到 'value_type' 类型的 null 指针
- 无法将类型为"类名 &"的非常量左值引用绑定到类型为"类名"的右值
- 引用绑定和复制构造函数/移动构造函数
- 将引用绑定到类型的值会删除限定符 MULTISET
- 无法将类型"int&"的非常量左值引用绑定到类型为"int"的右值
- 多态变体,并将一种类型的引用绑定到另一种类型的引用
- C++17:是编译器为(静态存储持续时间)const引用绑定创建的可修改的临时对象(和存储)