现代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
您提到的问题建议使用std::函数,但在与std::bind组合使用时并未强调(或根本未提及)它的价值 你的例子是最简单的,但是假设你有一个现代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::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,反之亦然,这取决于上下文。通常,人们不想仅仅因为在“容器遍历”过程中有一些非常局部/特定的需求而编写特殊函数
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; });
}