C++ 不同功能的容器?
我试图为不同的函数实现一个容器类,在这里我可以保存函数指针,并在以后使用它调用这些函数。我会尽量更准确地描述我的问题 例如,我有两个不同的测试函数:C++ 不同功能的容器?,c++,templates,containers,functor,variadic,C++,Templates,Containers,Functor,Variadic,我试图为不同的函数实现一个容器类,在这里我可以保存函数指针,并在以后使用它调用这些函数。我会尽量更准确地描述我的问题 例如,我有两个不同的测试函数: int func1(int a, int b) { printf("func1 works! %i %i\n", a, b); return 0; } void func2(double a, double b) { printf("func2 works! %.2lf %.2lf\n", a, b); } 我还有一系列
int func1(int a, int b) {
printf("func1 works! %i %i\n", a, b);
return 0;
}
void func2(double a, double b) {
printf("func2 works! %.2lf %.2lf\n", a, b);
}
我还有一系列变量,其中包含函数参数:
std::vector<boost::variant<int, double>> args = {2.2, 3.3};
struct TypeInfo {
int type_id; // for this example: 0 - int, 1 - double
template <class T>
void ObtainType() {
if (std::is_same<void, T>::value)
type_id = 0;
else if (std::is_same<int, T>::value)
type_id = 1;
else if (std::is_same<double, T>::value)
type_id = 2;
else
type_id = -1;
}
};
struct FunctionInfo {
public:
FunctionInfo() {}
FunctionInfo(BaseFunc *func, const TypeInfo& ret, std::vector<TypeInfo>& args) :
func_ptr(func), return_info(ret)
{
args_info.swap(args);
}
~FunctionInfo() {
delete func_ptr;
}
BaseFunc * func_ptr;
TypeInfo return_info;
std::vector<TypeInfo> args_info;
};
std::vector args={2.2,3.3};
我决定使用从某个基类派生的我自己的函子类(我考虑过使用虚拟方法):
类BaseFunc{
公众:
BaseFunc(){}
~BaseFunc(){}
};
模板
类Func;
模板
类Func:public BaseFunc{
类型定义R(*fptr_t)(Tn.);
fptr_t fptr;
公众:
Func():fptr(nullptr){
Func(fptr_t f):fptr(f){}
R运算符()(Tn…args){
返回fptr(参数…);
}
Func&运算符=(fptr\u t f){
fptr=f;
归还*这个;
}
};
我还决定存储一些关于函数及其参数的信息:
std::vector<boost::variant<int, double>> args = {2.2, 3.3};
struct TypeInfo {
int type_id; // for this example: 0 - int, 1 - double
template <class T>
void ObtainType() {
if (std::is_same<void, T>::value)
type_id = 0;
else if (std::is_same<int, T>::value)
type_id = 1;
else if (std::is_same<double, T>::value)
type_id = 2;
else
type_id = -1;
}
};
struct FunctionInfo {
public:
FunctionInfo() {}
FunctionInfo(BaseFunc *func, const TypeInfo& ret, std::vector<TypeInfo>& args) :
func_ptr(func), return_info(ret)
{
args_info.swap(args);
}
~FunctionInfo() {
delete func_ptr;
}
BaseFunc * func_ptr;
TypeInfo return_info;
std::vector<TypeInfo> args_info;
};
struct TypeInfo{
int type_id;//对于本例:0-int,1-double
模板
void ObtainType(){
if(std::is_same::value)
类型_id=0;
else if(std::is_same::value)
类型_id=1;
else if(std::is_same::value)
类型_id=2;
其他的
类型_id=-1;
}
};
结构函数信息{
公众:
FunctionInfo(){}
FunctionInfo(BaseFunc*func、const TypeInfo&ret、std::vector&args):
func_ptr(func),return_info(ret)
{
args_信息交换(args);
}
~FunctionInfo(){
删除func_ptr;
}
BaseFunc*func_ptr;
类型信息返回信息;
std::矢量参数信息;
};
现在我可以定义一个容器类:
class Container {
private:
template <size_t n, typename... T>
void ObtainTypeImpl(size_t i, TypeInfo& t)
{
if (i == n)
t.ObtainType<std::tuple_element<n, std::tuple<T...>>::type>();
else if (n == sizeof...(T)-1)
throw std::out_of_range("Tuple element out of range.");
else
ObtainTypeImpl<(n < sizeof...(T)-1 ? n + 1 : 0), T...>(i, t);
}
template <typename... T>
void ObtainType(size_t i, TypeInfo& t)
{
return ObtainTypeImpl<0, T...>(i, t);
}
public:
template <class R, class ...Args>
void AddFunc(const std::string& str, R(*func)(Args...)) {
BaseFunc * func_ptr = new Func<R(Args...)>(func);
size_t arity = sizeof...(Args);
TypeInfo ret;
ret.ObtainType<R>();
std::vector<TypeInfo> args;
args.resize(arity);
for (size_t i = 0; i < arity; ++i)
{
ObtainType<Args...>(i, args[i]);
}
cont_[str] = FunctionInfo(func_ptr, ret, args);
}
void CallFunc(const std::string& func_name,
std::vector<boost::variant<int, double>>& args_vec) {
auto it = cont_.find(func_name);
if (it != cont_.end())
{
// ???????
// And here I stucked
}
}
private:
std::map<std::string, FunctionInfo> cont_;
};
类容器{
私人:
模板
void obtaintypimpl(大小、类型信息和类型)
{
如果(i==n)
t、 ObtainType();
else如果(n==sizeof…(T)-1)
抛出std::超出范围(“元组元素超出范围”);
其他的
obtaintypimpl(i,t);
}
模板
无效获取类型(大小、类型信息和类型)
{
返回obtaintypimpl(i,t);
}
公众:
模板
void AddFunc(常量std::string和str,R(*func)(参数…){
BaseFunc*func_ptr=新func(func);
size\u t arity=sizeof…(Args);
类型信息检索;
ret.ObtainType();
std::向量args;
参数.调整大小(arity);
对于(大小i=0;i
然后我就结巴了
也许我走错了路?除了像Lua这样的脚本引擎之外,您是否可以建议任何解决此问题的方法?您可以执行以下操作:
class BaseFunc {
public:
virtual ~BaseFunc() = default;
virtual void Call(std::vector<boost::variant<int, double>>& args_vec) const = 0;
};
template <typename F> class Function;
template <typename R, typename... Args> class Function<R(Args...)> : public BaseFunc
{
public:
Function(R (*f)(Args...)) : f(f) {}
void Call(std::vector<boost::variant<int, double>>& args_vec) const override
{
Call(args_vec, std::index_sequence_for<Args...>());
}
private:
template <std::size_t ... Is>
void Call(
std::vector<boost::variant<int, double>>& args_vec,
std::index_sequence<Is...>) const
{
// Add additional check here if you want.
f(boost::get<Args>(args_vec.at(Is))...);
}
private:
R (*f)(Args...);
};
类BaseFunc{
公众:
virtual~BaseFunc()=默认值;
虚拟无效调用(std::vector和args_vec)const=0;
};
模板类函数;
模板类函数:public BaseFunc
{
公众:
函数(R(*f)(Args…):f(f){}
无效调用(std::vector和args_vec)常量覆盖
{
调用(AgsSvIEC,STD::DexxQuestStION/< P>),我认为我已经用Scott Myers更有效的C++看到了这个问题。我相信,他提供了一个解决方案。如果命名函数采用不同的参数,应该怎么做?失败,还是将值转换为预期类型?