静态全局数组中的函数

时间:2013-08-27 12:25:03

标签: c++ functor

我一直在试图弄清楚如何正确地将函数与id配对。到目前为止我一直在做的是C方式:

#include <iostream>

void PrintA();
void PrintB();

struct Function
{
    int id;
    void (*function)();
};

static const Function functions[] =
{
    {1, PrintA},
    {2, PrintB},
    {0, 0}
};

void PrintA()
{
    std::cout << "A" << std::endl;
};

void PrintB()
{
    std::cout << "B" << std::endl;
};

int main()
{
    int id = 1;

    for(int i = 0; functions[i].function != 0 ; i++)
    {
        if(functions[i].id == id)
        {
            functions[i].function();
        }
    }
}

我正在尝试使用C ++中的仿函数来实现相同的功能。我想我需要使用继承来将不同的函数存储在同一个数组中,这意味着我还需要为数组使用指针以防止切片。这样做的方法是否正确,有没有其他选择?

还有更简单的版本来调用操作符而不是我的操作吗?

#include <iostream>
#include <memory>

class Base
{
public:
    virtual void operator()() = 0;
};

class PrintA : public Base
{
public:
    void operator()();
};

void PrintA::operator()()
{
    std::cout << "A" << std::endl;
}

class PrintB : public Base
{
public:
    void operator()();
};

void PrintB::operator()()
{
    std::cout << "B" << std::endl;
}

struct Functor
{
    int id;
    std::shared_ptr<Base> function;
};

static Functor functors[] = 
{
    {1, std::shared_ptr<Base>(new PrintA)},
    {2, std::shared_ptr<Base>(new PrintB)},
    {0, 0}
};

int main()
{
    int id = 2;

    for(int i = 0; functors[i].function != 0 ; i++)
    {
        if(functors[i].id == id)
        {
            functors[i].function->operator()();
        }
    }
}
编辑:我必须使用相当旧的GCC版本,因此无法使用c ++ 11功能。但是,提升可用。我想std :: map会是一个好主意,但我真正要求的(并没有真正说清楚)是有更好的方法来存储函数而不是shared_ptr。我想std :: function / boost :: function方式就是这样做的。

2 个答案:

答案 0 :(得分:4)

在C ++ 11(或Boost中,如果你过去被困),{{1>}包装器中提供了这种类型的擦除;并且始终有function来执行基于ID的查找。所以你的例子很简单:

map

如评论中所述,如果真实情况与示例一样简单,您可以使用函数指针而不是#include <map> #include <functional> #include <iostream> // Note: This will be a lot messier if you're stuck with a pre-2011 compiler. // You'll need to define the functors (or functions) separately, and either // initialise the map with the result of a function call (possibly using // Boost.Assign), or write some code somewhere else to populate it. // // Or use an array, with lookup code like your C implementation. std::map<int, std::function<void()>> functors { {1, [](){std::cout << "A" << std::endl;}}, {2, [](){std::cout << "B" << std::endl;}} }; int main() { functors[2](); } (如果您愿意,仍然可以使用lambda初始化它),和一个数组(由id索引)而不是地图。我的例子假设您需要一个更通用的解决方案,将任意值映射到任意仿函数。

答案 1 :(得分:2)

简单:

#include <functional>
#include <iostream>
#include <vector>

void sayA() { std::cout << "A" << std::endl; }
void sayB() { std::cout << "B" << std::endl; }
struct Foo
{
  explicit Foo(int i) : i_(i) {}
  void operator()() const { std::cout << "foo " << i_<< "!" << std::endl; }
  int i_;
};

std::vector<std::function<void()>> funcs{ sayA, sayB, Foo(42) };

int main()
{
  for (const auto& f : funcs) f();
}