我正在做MSVC
static bool filter_entity(void* entity)
{
return entity == nullptr;
};
template<typename F>
static bool Dispatch(const F& filter)
{
return filter(nullptr);
};
int main()
{
void* ptr = new int();
if (Dispatch(std::bind(&filter_entity, ptr))) cout << "nullptr" << endl;
else cout << "intptr" << endl;
//ret: intptr
}
这是奇怪的,调用一个函数与constnullptr
参数实际上插入ptr
作为参数,我想知道这是否是一个未定义的行为。
也有一种方法来调用filter()
这个实例,并使模板和std::bind
在多种情况下显着?
From cppreference.com:
如果调用[被绑定对象]时提供的一些参数与[被绑定对象]中存储的占位符不匹配,则计算未使用的参数并丢弃。
问题的绑定对象没有占位符。那么
中的nullptr
return filter(nullptr);
被求值并丢弃,结果与if
相同。return filter();
。如果我们解释绑定,这与
相同return filter_entity(ptr);
(或者如果ptr
在作用域中)。如果您想在返回语句中使用nullptr
,则需要在std::bind
中使用std::placeholders::_1
。
接下来的问题可能是:为什么bind返回的对象会忽略额外的参数?
停止使用std::bind
。std::bind
不值得成为专家。不如成为lambdas的专家吧。
std::bind
是在c++11中从boost::bind
导入的,同时lambda也出现了。这是一个库解决方案,lambda解决了许多与它相同的问题。在c++11中,std::bind
可以做一些lambda不能做的事情;从那时起,lambda变得更加强大,现在这种情况已经不复存在了。
std::bind
充满了奇怪的角落。你正在见证其中的一个;老实说,是最普通的一个。
std::bind
不返回std::function
。std::bind
返回一个带有operator()
的未命名对象。当您在它上面调用operator()
时,它首先获取它的绑定参数(通过对引用的一些展开),根据占位符和绑定的子表达式进行一些重路由,
经过一个复杂的步骤之后,它就"静静地"了。丢弃额外的参数。
所以你将第一个参数绑定为nullptr;后一个非空值被求值并丢弃。