如何在C++中将变量用作函数?

3

在一些编程语言中(比如PHP和JavaScript),我可以使用一个变量作为函数。例如:

PHP: Class::$var_function();

这是否有可能在C ++中实现,而不需要使用switch或if语句?

必须指出,上面的PHP代码片段没有使用变量作为函数。它使用一个变量来动态创建标识符(一种“变量变量”形式)以进行方法调用。在下面的C/C++代码中,实际上使用了一个“句柄”(函数指针或std::function)来引用该函数,而标识符本身是稳定的。注释只能编辑5分钟(单击此框以关闭)。 - user166390
在JavaScript中,与PHP非常不同的是,函数是适当的一等值,并且像任何其他对象值一样运作:一个对象就是它本身。 - user166390
4个回答

4

是的,这样的变量被称为函数指针(非成员或静态成员函数)或指向成员函数的指针(非静态成员函数)。

另外,Boost、C++ TR1和C++11都提供了多态function包装器,它基本上是一种超级灵活的、通用的、泛型的函数指针类型。


4
这就是函数指针所能实现的功能。
int max(int v1, int v2) { return (v1 > v2) ? v1 : v2; }
int min(int v1, int v2) { return (v1 < v2) ? v1 : v2; }
int add(int v1, int v2) { return v1 + v2; }
int (*function)(int, int) = add;

int x = function(1, 3);  // x == 4
function = min;
int y = function(1, 3);  // x == 1

Etc.

您也可以在C++中获取成员函数的指针;但是,表示法略有不同。

您可以看到使用以下表示法通过指向函数的指针来调用函数的代码:

function = max;
int z = (*function)(1, 3);  // x == 3

这是旧式的、非标准的C语言。但它清楚地表明正在使用指向函数的指针(因此我仍然喜欢它并经常使用它)。


4

詹姆斯的回答可能是最好的。但是,如果你使用的是c++11兼容的编译器,你可以选择使用std::function。

例如:

#include <functional>
#include <iostream>
typedef std::function<void(int a)> callback_t;

class A {
public:
   void fn(int a) { std::cout << a << std::endl; }
};

void fn2(int b) { std::cout << a << std::endl; }

int main() {
   A a;
   callback_t c = std::bind(&A::fn, a, std::placeholders::_1);
   c(1);

   c = fn2;
   c(2);

   return 0;
}

而且,还有一个boost版本(我从未使用过,所以可能不正确):
#include <boost/function.hpp>
#include <iostream>
typedef boost::function<void(int a)> callback_t;

class A {
public:
   void fn(int a) { std::cout << a << std::endl; }
};

void fn2(int b) { std::cout << a << std::endl; }

int main() {
   A a;
   callback_t c = boost::bind(&A::fn, a, boost::placeholders::_1);
   c(1);

   c = fn2;
   c(2);

   return 0;
}

我在typedef声明中收到编译器错误:error: expected initializer before ‘<’ token。 - Calvin Froedge
你使用的编译器是什么?如果是g++,请传递-std=c++0x参数。 - Naddiseo
cc1plus: 错误:无法识别命令行选项“-std=c++0x”。是的,我正在使用g++(Mac OS X)。 - Calvin Froedge
你需要使用一个比较新的版本,我认为大于4.5就可以了。另一种选择是使用James上面提到的boost库。我会更新我的帖子,添加一个boost版本。 - Naddiseo
1
我不确定这是否仍然是一个问题,但是A a();不是声明一个返回类A且不带参数的本地函数吗?我认为你只需要A a; - dreamlax
显示剩余2条评论

0
除了其他答案之外,您可以通过定义函数调用运算符使任何用户定义类型的对象像函数(甚至像一组重载函数)一样运作:
class MyClass
{
public:
  MyClass(): member(42) {};
  void operator()(int i) { std::cout << (member=i) << '\n'; }
  void operator()() { std::cout << member++ << '\n'; }
private:
  int member;
};

int main()
{
  MyClass foo;

  foo();   // prints 42
  foo();   // prints 43
  foo(23); // prints 23
  foo();   // prints 24
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接