【问题标题】:Why can I std::bind successfully with the wrong parameters?为什么我可以使用错误的参数成功地 std::bind?
【发布时间】:2020-10-23 23:15:24
【问题描述】:
#include <iostream>
#include <functional>

using callback = std::function<void(int, void*)>;

void AddCallback(callback cb) {}

void foo(int i) {}

int main() {
  auto f = std::bind(&foo, std::placeholders::_1);
  AddCallback(f);
}

我用 g++ 9.3.0 和 clang++ 10.0.0 尝试了代码,它们都编译结束没有错误。

绑定结果和回调的类型是否相同?一个是std::function&lt;void(int, void*)&gt;,另一个等于std::function&lt;void(int)&gt;?为什么我可以调用不同类型的AddCallback()

【问题讨论】:

    标签: c++ c++11 stdbind


    【解决方案1】:

    您似乎可以将更多参数传递给bind 的结果而不是必要的,它们将被默默地忽略。

    如果在对 [bind] 的调用中提供的某些参数与任何占位符都不匹配...,则评估并丢弃未使用的参数。

    ——cppreference

    【讨论】:

    • 绑定结果和回调的类型是否相同?为什么我可以调用不同类型的 AddCallback()?一个是std::function,另一个是等于std::function?
    • @Xingx1 因为std::function 可以从您可以使用指定参数调用的任何可调用对象构造。如果您可以使用指定类型的参数调用std::bind 的结果,则可以将其转换为std::function
    • std::bind 的结果是一个带有模板化operator() 的类型。它不是std::function 的实例化,而是std::function&lt;void(int, void*)&gt; 有一个接受活页夹类型的转换构造函数
    【解决方案2】:

    不是你的 AddCallback() 接受不同的类型,而是类型推导造成混乱;

    例如尝试使用

    std::function<void(int)> f = std::bind(&foo, std::placeholders::_1);
    

    或者添加回调函数我们会给你错误

    错误(活动) E0312 没有合适的用户定义转换 "std::function" 到 "callback" 存在

    【讨论】:

    • 问题是std::bind调用的结果不是std::function,它是一个未指定的类型,可以转换为std::function。如果您将f 的类型更改为std::function&lt;void(int, void*)&gt;,它将完美编译。
    • 确实如此。这种类型的 std::bind 是未指定的,但他的问题是“为什么我可以用不同的类型调用 AddCallback()?”
    猜你喜欢
    • 2015-05-23
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多