C++ 为什么std::function可以隐式转换为具有更多参数的std::function?;

C++ 为什么std::function可以隐式转换为具有更多参数的std::function?;,c++,c++11,std-function,stdbind,C++,C++11,Std Function,Stdbind,我有以下资料: void print_str(std::shared_ptr<std::string> str) { std::cout << str->c_str() << std::endl; } int main() { auto str = std::make_shared<std::string>("Hello"); std::function<void()> f = std

我有以下资料:

void print_str(std::shared_ptr<std::string> str) {
    std::cout << str->c_str() << std::endl;
}

int main() {
    auto str = std::make_shared<std::string>("Hello");
    std::function<void()> f = std::bind(print_str, str);

    f(); // correctly print: Hello

    return 0;
}
void print_str(std::shared_ptr str){

std::cout c_str()std::bind所做的是正确的。它使用您为print_str调用提供的值(str)。因此您不需要再指定它,它将始终被绑定值替换

#include <iostream>
#include <functional>

int sum(int value1, int value2) {
    return value1 + value2;
}

int main() {

    std::function<int(int, int)> f1 = std::bind(sum, std::placeholders::_1, std::placeholders::_1);
    std::function<int(int)> f2 = std::bind(sum, 10, std::placeholders::_1);
    std::function<int()> f3 = std::bind(sum, 100, 200);
    std::function<int(int)> f4 = std::bind(sum, std::placeholders::_1, 200);

    int a = 1;
    int b = 2;

    std::cout << "the sum of " << a << " and " << b << " is: " << f1(a, b) << std::endl;
    std::cout << "the sum of " << 10 << " and " << b << " is: " << f2(b) << std::endl;
    std::cout << "the sum of " << 100 << " and " << 200 << " is: " << f3() << std::endl;
    std::cout << "the sum of " << 200 << " and " << b << " is: " << f4(b) << std::endl;

    return 0;
}
f1
只绑定占位符而不绑定任何值,并返回一个
int(int,int)
like函数

f2
绑定一个值和一个占位符,并返回一个
int(int)
类函数

f3
绑定两个值,不使用占位符,并返回一个
int()
类函数

f4
f2
类似,不同之处在于占位符现在是第一个参数,而不是第二个参数

您的代码属于
f3
情况

我认为
std::bind(print\u str,str)
的类型是
std::function

不,std::bind(print\u str,str)
的类型是一个未指定的函子类型,类似

class binder
{
    void(*f)(std::shared_ptr<std::string>);
    std::shared_ptr<std::string> p;
public:
    template<typename... Args>
    void operator()(Args... ) { f(p); }
};
类绑定器
{
无效(*f)(标准::共享的ptr);
std::共享的ptr p;
公众:
模板
void运算符()(Args…{f(p);}
};

请注意,这可以使用任何参数调用,也可以不使用任何参数。

您在这里遇到的情况是正确的,并且正是按照
std::bind
的设计进行的

简单地说: 它将采用
n
参数的函数转换为采用
m
参数的函数(其中
n>=m
)。 在您的特定情况下,您给它一个带一个参数的函数,然后返回一个带零个参数的函数。这个新函数将在内部调用
print\u str
,并始终将
str
作为参数传递

旁注:

由于C++11中有lambda,
std::bind
有点多余。 您所做的与此完全相同:

void print_str(std::shared_ptr<std::string> str) {
    std::cout << str->c_str() << std::endl;
}

int main() {
    auto str = std::make_shared<std::string>("Hello");
    std::function<void()> f = [=]() { print_str(str); };

    f(); // correctly print: Hello

    return 0;
}
void print_str(std::shared_ptr str){

std::cout c_str()不,这不是std::bind(print_str,str)的类型
。毕竟,生成的函数不带任何参数,原始函数的唯一参数已绑定,那么第二个参数将从何而来?谢谢您的回答!很容易理解。在运行您的代码后,我的另一个问题是,为什么
std::function f5=std::bind(sum,1,2)
编译是否正确?换句话说,在
auto f=std::bind(sum,1,2)中
f
的推断类型是什么;
?stl不指定std::bind的返回类型。auto f具有functor类型,您可以传递任意数量的参数,但至少要传递bind指定的占位符数量。其他参数将不被指定used@Griyn这是一个相当有趣的观察结果。你应该问这个,而不是你真正想要的搜索;-)看起来
std::bind
有一些不可预测的“特性”:@sebrockm谢谢!这也有助于解决我的困惑。
void print_str(std::shared_ptr<std::string> str) {
    std::cout << str->c_str() << std::endl;
}

int main() {
    auto str = std::make_shared<std::string>("Hello");
    std::function<void()> f = [=]() { print_str(str); };

    f(); // correctly print: Hello

    return 0;
}