现代c++;函数指针的替代方法 我一直使用函数指针,就像C++中的这个格式。我有时确实有一些用途,我想知道在c++11/14中是否还引入了其他东西作为它们的替代品 #include <iostream> using namespace std; void sayHello(); void someFunction(void f()); int main() { someFunction(sayHello); return 0; } void sayHello(){ std::cout<<"\n Hello World"; } void someFunction(void f()){ f(); } #包括 使用名称空间std; void sayHello(); void函数(void f()); int main(){ someFunction(sayHello); 返回0; } void sayHello(){ std::cout

现代c++;函数指针的替代方法 我一直使用函数指针,就像C++中的这个格式。我有时确实有一些用途,我想知道在c++11/14中是否还引入了其他东西作为它们的替代品 #include <iostream> using namespace std; void sayHello(); void someFunction(void f()); int main() { someFunction(sayHello); return 0; } void sayHello(){ std::cout<<"\n Hello World"; } void someFunction(void f()){ f(); } #包括 使用名称空间std; void sayHello(); void函数(void f()); int main(){ someFunction(sayHello); 返回0; } void sayHello(){ std::cout,c++,pointers,c++11,function-pointers,C++,Pointers,C++11,Function Pointers,您提到的问题建议使用std::函数,但在与std::bind组合使用时并未强调(或根本未提及)它的价值 你的例子是最简单的,但是假设你有一个 std::function<void (int, int)> f ; std::函数f; 函数指针可以做或多或少相同的事情。但是假设您需要一个函数g(int),它是f,第二个参数绑定为0。对于函数指针,您不能做很多事情,而对于std::function,您可以这样做: std::function<void(int)> g = s

您提到的问题建议使用std::函数,但在与std::bind组合使用时并未强调(或根本未提及)它的价值

你的例子是最简单的,但是假设你有一个

std::function<void (int, int)> f ;
std::函数f;
函数指针可以做或多或少相同的事情。但是假设您需要一个函数g(int),它是f,第二个参数绑定为0。对于函数指针,您不能做很多事情,而对于std::function,您可以这样做:

std::function<void(int)> g = std::bind(f, _1, 0) ;
std::function g=std::bind(f,_1,0);
我确实看了一下这个问题,但什么也看不懂 相对于传统使用函数指针的优势。我也会 我想问一下,这有什么不对(不推荐)的地方吗 使用函数指针,因为我从未见过有人使用它们

  • 普通的“全局”函数通常没有/不可能有状态。虽然在函数编程范例中,在遍历过程中有状态并不一定好,但有时当状态与已更改的内容(例如启发式)正交关联时,状态可能会派上用场。在这里,函子(或函数对象)具有优势

  • 普通函数的组合不是很好(创建低级函数的高级函数)

  • 正常函数不允许动态绑定其他参数

  • 有时,普通函数可以替代lambda,反之亦然,这取决于上下文。通常,人们不想仅仅因为在“容器遍历”过程中有一些非常局部/特定的需求而编写特殊函数


作为传统函数指针的替代方案,C++11引入了可简化函数指针sintax的函数指针。下面是如何创建“模板”函数指针的示例:

template <typename R, typename ...ARGS> using function = R(*)(ARGS...);
使用function=R(*)(ARGS…)的模板; 它可以这样使用:

void foo()                { ... }
int bar(int)              { ... }
double baz(double, float) { ... }

int main()
{
    function<void>                  f1 = foo;
    function<int, int>              f2 = bar;
    function<double, double, float> f3 = baz;

    f1(); f2({}); f3({}, {});
    return 0;
}
void foo(){…}
整型条(整型){…}
双baz(双,浮点){…}
int main()
{
函数f1=foo;
功能f2=棒;
函数f3=baz;
f1();f2({});f3({},{});
返回0;
}
此外,它还可以灵活地处理函数重载:

void overloaded(int)      { std::cout << "int version\n"; }
void overloaded(double)   { std::cout << "double version\n"; }

int main()
{
    function<void, int>    f4 = overloaded;
    function<void, double> f5 = overloaded;

    f4({}); // int version
    f5({}); // double version
    return 0;
}
void重载(int){std::cout
我还想问一下,有什么问题吗(不推荐)
因为我从来没见过有人使用函数指针
他们

是的。函数指针是非常糟糕的东西。首先,它们不支持泛型-所以你不能使用一个函数指针,比如说,对任何
T
都使用
std::vector
。其次,它们不支持绑定状态,所以如果在将来的任何时候,任何人都希望引用其他状态,那么它们是完整的这尤其糟糕,因为这包括成员函数的
This

在C++11中获取函数有两种方法。第一种是使用模板。第二种是使用std::function

模板有点像这样:

template<typename T> void func(F f) {
    f();
}
模板无效函数(F){
f();
}
这里的主要优点是它可以接受任何类型的函数对象,包括函数指针、lambda、functor、bind result等等,F可以有任意数量的函数调用重载和任意签名,包括模板,并且它可以有任意大小和任意绑定状态。因此它具有超级复制灵活性。它还可以作为编译器可以内联运算符并直接在对象中传递状态

int main() {
    int x = 5;
    func([=] { std::cout << x; });
}
intmain(){
int x=5;

func([=]{std::cout可能是try lambdas的副本:)@AndrewLavq,有一些繁重的打印功能(虽然不是应用程序,只是为了演示),如果我使用lambdas,这会影响可读性。这看起来很有希望,但我不明白为什么我要使用另一个参数比f少一个的函数g?换句话说,std::bind和std::function可能的实际用例是什么?@hg_git:假设您有一个
比较(字符串,字符串,bool区分大小写)
。当您需要不区分大小写的比较时,您可能需要传递
std::bind(compare,\u 1,\u 2,false)
。@hg\u git如果您想要具有延迟参数的函数就可以了。想想一个包含“要做的事情”列表的工作线程。非常常见的是:一个具有“撤消列表”的应用程序。将记录每个用户步骤,并将函数调用放入包含参数的列表中(绑定)。如果要撤消,只需向后调用列表,然后执行与函数相反的操作。@Klaus:与简单地快照状态相比,这种撤消列表作为一种策略是相当死气沉沉的。编写“撤消”命令因为与COW状态相比,每个可能的用户操作都是可怕的,在COW状态下,任何操作都可以恢复状态。@这只是一个例子!如果数据非常复杂和庞大,那么几乎不可能存储一个长撤消列表的每个状态。因此我不敢相信“撤消功能”已经失效。但无论如何:这是一个例子:-)不,不,绝对不是。如果你不想使用std::function的优点,那么就使用一个模板-一个真正的模板,而不仅仅是一个语法简化的别名。
模板void func(F)
-哪一个是打字错误-t或F类型?
int main() {
    int x = 5;
    func([=] { std::cout << x; });
}