Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不同功能的容器?_C++_Templates_Containers_Functor_Variadic - Fatal编程技术网

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++看到了这个问题。我相信,他提供了一个解决方案。如果命名函数采用不同的参数,应该怎么做?失败,还是将值转换为预期类型?