bind如何知道何时强制转换为指针
How does bind know when to cast to pointer?
我在c++中发现了一件有趣的事情。
using namespace std;
struct Person {
string name;
bool check() {
return name == "carol";
}
};
int main()
{
Person p = { "Mark" };
list<Person> l;
l.push_back(p);
if (find_if(l.begin(), l.end(), bind(&Person::check, std::placeholders::_1)) == l.end())
{
cout << "Not found";
}
return 0;
}
上面的if语句正常工作。当解引用迭代器for_each获取一个对象并将其传递给函数时。不知何故,bind知道(在绑定时)指针到成员函数的第一个参数应该是指针。但是在下面的示例中,它不知道这一点,并且由于从Person到Person*的强制转换而抛出错误。那么bind是如何工作的呢?如何在下面的例子中传递一个指针?
find_if(l.begin(), l.end(), bind(mem_fun(&Person::check), std::placeholders::_1)) == l.end()
我已经想到了这样的东西,但我不确定这是否是最好的方法。
find_if(l.begin(), l.end(), bind([](Person& p) { return p.check(); }, std::placeholders::_1)) == l.end()
您看到的错误与bind
无关,它是mem_fun
的错误(已弃用,将在下一个c++版本中删除)。当你用mem_fun
包装一个指向成员函数的指针时,你需要传递一个指针到你想要调用成员函数的实例。
find_if
将解引用迭代器并将结果传递给它的谓词,这意味着您试图将Person&
而不是Person*
传递给mem_fun_t
。如果你想传递一个引用,那么用mem_fun_ref
代替。下面的代码将编译
find_if(l.begin(), l.end(), bind(mem_fun_ref(&Person::check), std::placeholders::_1))
// ^^^^^^^^^^^
正如Barry指出的,你甚至不需要在表达式中使用bind
,下面的代码也可以
find_if(l.begin(), l.end(), mem_fun_ref(&Person::check))
或使用mem_fun
/mem_fun_ref
的c++ 11替代品,mem_fn
find_if(l.begin(), l.end(), mem_fn(&Person::check))
最后,还可以使用lambda表达式
find_if(l.begin(), l.end(), [](Person& p) { return p.check(); })
mem_fun
不工作的原因是:
创建成员函数包装器对象,从模板参数推断目标类型。包装器对象需要一个指向类型为
T
的对象的指针作为其operator()
的第一个参数。
要完成同样的事情,您需要使用std::mem_fun_ref
(不需要bind
):
find_if(l.begin(), l.end(), std::mem_fun_ref(&Person::check))
但实际上,你应该更喜欢更通用的std::mem_fn
,它允许这两个,另外,前两个将在c++ 17中被弃用:
函数模板std::mem_fn为指向成员的指针生成包装器对象,可以存储、复制和调用指向成员的指针。在调用
std::mem_fn
时,指向对象的引用和指针(包括智能指针)都可以使用。
std::bind
同样允许同时使用引用或指针:
如Callable中所述,当调用指向非静态成员函数的指针或指向非静态数据成员的指针时,第一个参数必须是指向其成员将被访问的对象的引用或指针(可能包括
std::shared_ptr
和std::unique_ptr
等智能指针)。
- 转换指针引用的字符串
- 无法向上转换指针到指针参数
- 混合转换指针和引用
- 堆栈对象的强制转换指针
- 基类到派生模板类的强制转换指针,而不知道类型
- 删除类型转换指针的最佳方法
- 管理到本机值类转换:强制转换指针是否安全?
- 转换指针类型
- 为什么函数不能正确强制转换指针(从基类到派生类)
- 当我们递增下面的类型转换指针时会发生什么?
- 类型强制转换指针构造函数调用
- 如何转换(指针向量)-->(指向指针数组的指针)
- 如何从类功能转换指针
- 在C++对象中:我应该使用父类强制转换指针,还是应该使用实际类本身进行强制转换
- Delphi中的类型转换指针添加
- C++分段错误(核心转储)错误 - 强制转换指针/将函数值返回到线程
- 以C++和运算符优先级键入指向数组成员的强制转换指针
- C++动态强制转换指针的内存清理
- 转换指针和引用的好处
- 在c++中转换指针