std::function 的模板类型是否被 std::bind 分离为未定义的行为?

Is template type of a std::function detached by std::bind an undefined behavior?

我正在研究 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 对多种情况都有意义?

来自cppreference.com

If some of the arguments that are supplied in the call to [the bound object] are not matched by any placeholders stored in [the bound object], the unused arguments are evaluated and discarded.

问题中的绑定对象没有占位符。所以

中的 nullptr
return filter(nullptr);

被评估并丢弃,结果与if

相同
return filter();

被叫了。如果我们解释绑定,这与

相同
return filter_entity(ptr);

(或者如果 ptr 在范围内)。如果要在 return 语句中使用 nullptr,则需要在 std::bind.

中使用 std::placeholders::_1

对此的后续问题可能是 Why do objects returned from bind ignore extra arguments?

停止使用 std::bindstd::bind 不值得成为专家。请成为 lambda 专家。

std::bind 是在 at the same time lambdas arrived. It was a library solution that lambdas solved many of the same problems as it did. In 中从 boost::bind 导入的 std::bind 可以做一些 lambda 做不到的事情;从那时起 lambda 变得更加 poeerful,这不再是真的。

std::bind到处都是奇怪的角落。你正在目睹其中之一;老实说,比较行人之一。


std::bind 不 return 一个 std::functionstd::bind returns 一个带有 operator() 的未命名对象。当您在其上调用 operator() 时,它首先获取其绑定参数(引用的一些解包),根据占位符和绑定子表达式进行一些重新路由,.

经过一个复杂的步骤后,它会“默默地”丢弃额外的参数。

因此您将第一个参数绑定到 nullptr;后面的非 null 被评估并丢弃。