我想知道在C ++中是否有办法做到这一点?
void func1(const std::string& s)
{
std::cout << s << std::endl;
}
void func2(int me)
{
std::cout << me << std::endl;
}
int main()
{
std::map<std::string, boost::function< ??? > > a_map;
a_map["func1"] = &func1;
a_map["func1"]("HELLO");
}
有没有办法在上面使用boost功能和地图做什么?
答案 0 :(得分:2)
您可能无法使用std::map
,因为它是一个同质的容器。尝试,例如boost::variant
(他们支持访客模式)或boost::tuple
答案 1 :(得分:2)
有一些方法来存储函数,问题是,为了能够使用所需的参数调用函数,你必须知道函数的调用签名,如果你有这些信息,你不妨使用单独的地图,或使用比boost :: function更复杂的对象。
如果你愿意做一些工作并拥有有限数量的签名,你可以这样做:
class MultiFunc
{
protected:
MultiFunc() {}
public:
typedef void (*stringFunc)(const std::string&);
typedef void (*intFunc)(int);
static MultiFunc *Create(stringFunc function);
static MultiFunc *Create(intFunc function);
virtual void operator()(const string &) { throw exception(); }
virtual void operator()(int) { throw exception(); }
virtual ~MultiFunc();
};
class MultiFuncString : public MultiFunc
{
private:
stringFunc Function;
public:
MultiFuncString(stringFunc function) : Function(function) {}
virtual void operator()(const string &arg) { Function(arg); }
};
class MultiFuncInt : public MultiFunc
{
private:
intFunc Function;
public:
MultiFuncInt(intFunc function) : Function(function) {}
virtual void operator()(int arg) { Function(arg); }
};
MultiFunc *MultiFunc::Create(MultiFunc::stringFunc function)
{
return new MultiFuncString(function);
}
MultiFunc *MultiFunc::Create(MultiFunc::intFunc function)
{
return new MultiFuncInt(function);
}
void func1(const std::string& s)
{
std::cout << s << std::endl;
}
void func2(int me)
{
std::cout << me << std::endl;
}
int main()
{
map<string, MultiFunc *> a_map;
a_map["func1"] = MultiFunc::Create(&func1);
(*a_map["func1"])("Hello");
a_map["func2"] = MultiFunc::Create(&func2);
(*a_map["func2"])(3);
// Remember to delete the MultiFunc object, or use smart pointers.
}
输出:
Hello 3
不幸的是,你不能制作模板化的虚函数,或者你很容易将这一切都概括。
答案 2 :(得分:2)
你要做的事听起来有点奇怪。通常,您将使容器成为具有相同签名的抽象类型或对象或函数的集合。否则,在迭代容器时,您如何知道如何调用该函数?我喜欢使用已知签名使容器成为函数对象的集合,然后使用Boost.Bind存储使用其他参数调用函数的闭包。
例如:
typedef boost::function<void, void> Function;
typedef std::map<std::string, Function> Functions;
Functions functions:
void foo()
{
...
}
functions["foo"] = foo;
void bar(std::string &s)
{
...
}
// binds the value "hello" to the s parameter
functions["bar"] = boost::bind(bar, "hello");
答案 3 :(得分:0)
请阅读以下链接。它讨论了使用boost :: bind来存储std :: map
中的函数指针http://www.gamedev.net/community/forums/topic.asp?topic_id=526381&whichpage=1�
答案 4 :(得分:0)
存储接口:
struct IStringData
{
virtual std::string get() const = 0;
virtual ~IStringData() {}
};
并制作实现,一个只保存字符串值,其他实现将存储仿函数,也许你将来会有其他实现。
答案 5 :(得分:0)
没有。你不能。因为boost :: function不是多态的,所以它在那里分解。 (它需要一组固定的参数类型。)
但是,有人谈到在升级邮件列表上朝这个方向开展的工作,所以请搜索档案,看看是否有一些代码可以使用。
解决方法是使用boost :: function,但是你需要向地图添加不是你的真实函数(即func1 / func2),而是从任意容器中提取类型并调用实际函数的调度函数。 (并且如果它错了就保释,就像在任何动态的语言中一样。)