问题描述
我正在研究 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
}
奇怪的是,使用 const nullptr
参数调用函数实际上将 ptr
作为参数插入,我想知道这是否是未定义的行为。
还有没有办法为此实例调用 filter()
并使模板和 std::bind
在多种情况下都有意义?
解决方法
如果在对 [绑定对象] 的调用中提供的某些参数与存储在 [绑定对象] 中的任何占位符都不匹配,则未使用的参数将被评估并丢弃。
问题中的绑定对象没有占位符。所以
中的nullptr
return filter(nullptr);
求值并丢弃,结果与if相同
return filter();
被调用。如果我们解释绑定,这与
相同return filter_entity(ptr);
(或者如果 ptr
在范围内)。如果要在 return 语句中使用 nullptr
,则需要在 std::placeholders::_1
中使用 std::bind
。
对此的后续问题可能是Why do objects returned from bind ignore extra arguments?
,停止使用 std::bind
。 std::bind
不值得成为专家。而是成为 lambdas 的专家。
std::bind
从 c++11 中的 boost::bind
导入,同时 lambdas 到达。这是一个库解决方案,lambdas 解决了许多与它相同的问题。在 c++11 中,std::bind
可以做一些 lambdas 不能做的事情;从那以后 lambda 变得更加诗意,这不再是真的。
std::bind
充满了奇怪的角落。你正在见证其中之一;老实说,其中一个比较行人。
std::bind
不返回 std::function
。 std::bind
返回带有 operator()
的未命名对象。当您对其调用 operator()
时,它首先获取其绑定参数(或者是对引用进行一些解包),根据占位符和绑定子表达式进行一些重新路由。
在那里完成一个复杂的步骤后,它会“悄悄地”丢弃额外的参数。
所以你将第一个参数绑定到 nullptr;后面的非空值被评估并丢弃。