使用变量参数映射函数并通过字符串c ++调用 [英] Mapping functions with variable arguments and calling by string c++

查看:115
本文介绍了使用变量参数映射函数并通过字符串c ++调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一些公平的想法如何映射函数与变量参数,返回类型的int,并通过字符串调用它。

只是一个例子...

I would like to have some fair idea how to map functions with variable arguments,return type of int and call it by a string..
Just for an example...

int func1(int a, int b);
int func2(int a1, int b1 , int* c1);
int func3(char* dummy);
int func4(double x, long y, int z, char** table);  
int func5(double d1, double b1);  
int func6(int* p, double* q, int i);

我只需要一个常用的函数

I just need a common function called

int CallFunction("funcname", param1, param2, ...); 

例如

CallFunction("func1", 10, 20); /* calling function func1 and return func1 result*/



我知道如何使用函数指针映射函数常量参数,但可变参数似乎是复杂的..任何人都可以淋shower一些想法如何做到。

I know how to map functions using functions pointers having constant arguments but variable arguments seems to be complicated.. could anyone shower some idea how to do it.

我甚至探索了Variadic模板..但似乎复杂的函数使用字符串..

I even explored Variadic templates.. But seems to complicated calling functions using strings..

推荐答案

我不知道这是不是你要的,但无论如何...

I'm not sure if this is what you're looking for, but anyway...

boost.any 没有使它成为标准,并且,如果你不知道它是什么,它允许你存储任何C ++值在一个单一的类型( any ),如果你知道类型,就得到它。下面是一个玩具实现它:

boost.any didn't make it into the standard, and, in case you don't know what it is, it allows you to store any C++ value in a single type (any) and get it back if you know the type. The following is a toy implementation of it:

struct TypeHandler {
    void* (*copyFrom)(void *src);
    void (*destroy)(void *p);
};

template<typename T>
TypeHandler *thandler() {
    struct THandler {
        static void *copyFrom(void *p) { return new T(*(T *)p); }
        static void destroy(void *p) { delete (T *)p; }
    };
    static TypeHandler th = { &THandler::copyFrom, &THandler::destroy };
    return &th;
}

TypeHandler 指向知道如何复制以及如何销毁特定C ++类型的函数的指针。 A Value 可以容纳任何类型,因为它由 void * 和指向 TypeHandler 。当需要在实例上复制或销毁时,它会询问特定的类型处理函数...

TypeHandler contains two pointer to functions that know how to copy and how to destroy a specific C++ type. A Value can hold any type because it's composed of a void * and a pointer to a TypeHandler. When copying or destroying is required on the instance it asks to the specific type handler function...

struct Value {
    TypeHandler *th;
    void *p;

    Value(const Value& other) : th(other.th), p(th->copyFrom(other.p)) { }
    template<typename T> Value(const T& x) : th(thandler<T>()), p(new T(x)) { }
    ~Value() { th->destroy(p); }

    Value& operator=(const Value& other) {
        if (this != &other) {
            th->destroy(p);
            th = other.th;
            p = th->copyFrom(other.p);
        }
        return *this;
    }

    template<typename T>
    Value& operator=(const T& other) {
        th->destroy(p);
        th = thandler<T>();
        p = new T(other);
        return *this;
    }

    template<typename T>
    T& to() const {
        if (th != thandler<T>()) throw Error("type mismatch");
        return *(T*)p;
    }
};

请注意, Value 是可复制的,通过值传递并且可以通过函数返回。
任何可复制对象都可隐式转换为 Value ,我也可以将其转换回原来的类型到< T>

Note that Value is copyable and can be passed by value and can be returned by functions. Any copyable object is implicitly convertible into a Value and I can also convert it back to the original type with to<T>().

std::map<std::string, Value (*)(const Value&)> map1;
std::map<std::string, Value (*)(const Value&, const Value&)> map2;

Value call(const std::string& name, const Value& x1) {
    return map1.at(name)(x1);
}

Value call(const std::string& name, const Value& x1, const Value& x2) {
    return map2.at(name)(x1, x2);
}


$ b $ p

这里我为1和2参数创建了显式映射。可能是这样可以使用C ++ 11可变参数模板,我没试过。在C ++ 03库中,通常会看到这种复制粘贴到n = 20以覆盖合理的情况。

Here I've created explicit maps for 1 and 2 arguments. May be this can be done using C++11 variadic templates, I didn't try. In C++03 libraries it's common to see this kind of stuff copy-n-pasted up to say n=20 to cover reasonable cases.

为了简化函数的注册,我写了两个丑陋的宏。可能是这样做也可以使用可变参数宏或模板(我不是很确定,特别是在地图中自动注册包装器)。

To simplify registration of functions I wrote two ugly macros. May be this can be done also using variadic macros or templates (I'm not so sure about it, especially the automatic registration of the wrapper in the map).

#define regfunc1(name, t1)                   \
    Value name(const Value& x1) {            \
        return name(x1.to<t1>());            \
    }                                        \
    struct name##_ {                         \
        name##_() { map1[#name]=&name; }     \
    } name##_instance

#define regfunc2(name, t1, t2)                           \
    Value name(const Value& x1, const Value& x2) {       \
        return name(x1.to<t1>(), x2.to<t2>());           \
    }                                                    \
    struct name##_ {                                     \
        name##_() { map2[#name]=&name; }                 \
    } name##_instance



4。使用



4. Use

double square(double x) {
    return x*x;
}

double hyp2(double x, double y) {
    return x*x+y*y;
}

int mylen(const std::string& s) {
    return s.size();
}


regfunc1(square, double);
regfunc2(hyp2, double, double);
regfunc1(mylen, std::string);

int main() {
    Value x = 42;
    Value y = std::string("This is a test");
    Value z = 3.14;
    printf("%0.3f\n", call("square", z).to<double>());
    printf("%0.3f\n", call("hyp2", z, z).to<double>());
    printf("mylen(\"%s\") = %i\n",
           y.to<std::string>().c_str(),
           call("mylen", y).to<int>());
    return 0;
}

这篇关于使用变量参数映射函数并通过字符串c ++调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆