我一直在试图弄清楚如何正确地将函数与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方式就是这样做的。
答案 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();
}