c++ - C++ 包装器中的 C 可变参数函数

标签 c++ c variadic-functions

我正在围绕 C Python API (Python 1.5) 重写一个 C 包装器,我注意到函数 Py_VaBuildValue 使用可变数量的参数。我想知道我是否必须在我的 C++ 函数包装器中使用相同的方法来传递给这个函数,或者是否有更多的 C++ 方法来处理这个问题?

我知道可变参数函数可能会带来数不清的麻烦,所以如果有更好的方法,我宁愿避免使用。

编辑:

所以这是我需要制作成 C++ 函数的 C 代码:

int Set_Global(char *modname, char *varname, char *valfmt, ... /* cval(s) */) {

    int result;
    PyObject *module, *val;                             // "modname.varname = val"
    va_list cvals;
    va_start(cvals, valfmt);                            // C args after valfmt

    module = Load_Module(modname);                      // get/load module
    if (module == NULL) 
        return -1;
    val = Py_VaBuildValue(valfmt, cvals);               // convert input to Python
    va_end(cvals);
    if (val == NULL) 
        return -1;
    result = PyObject_SetAttrString(module, varname, val); 
    Py_DECREF(val);                                     // set global module var
    return result;                                      // decref val: var owns it
}

所以我使用 std::string 而不是 char* 创建相同的函数,我想将省略号更改为更像 c++ 的东西,但是我可以在函数内部传递给 Py_VaBuildValue。

最佳答案

如果你想变得聪明并且不害怕一些沉重的模板魔法,应该可以生成(或按摩)valfmt 以始终匹配你想要传递的类型(我假设它使用类似于 printf 的格式说明符,但该技术适用于任何类型的格式说明)。你可以这样做:

template <typename T> struct format_trait;
template <> struct format_trait<int> { static const char * format() { return "%i"; }};
template <> struct format_trait<unsigned> { static const char * format() { return "%u"; }};
... // and so on for each type you want to use

template <typename Arg1>
int Set_Global(const std::string &modname, const std::string &varname, const Arg1 &arg1)
{
    return ::Set_Global(modname.c_str(), varname.c_str(), format_trait<Arg1>::format(), arg1);
}

template <typename Arg1, typename Arg2>
int Set_Global(const std::string &modname, const std::string &varname, const Arg1 &arg1, const Arg2 &arg2)
{
    return ::Set_Global(modname.c_str(), varname.c_str(),
        std::string(format_trait<Arg1>::format()) + format_trait<Arg2>::format(),
        arg1, arg2);
}
... // Repeat up to number of argument you reasonably expect to need or use C++0x variadic templates.

这是一种简单的方法,其中每个值都以默认方式格式化并组合在一起。如果你想要更复杂的东西,你可以创建一个函数,它将获取 valfmt 字符串和正确的格式说明符(从特征中获取)并将修复格式字符串以匹配。

关于c++ - C++ 包装器中的 C 可变参数函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5391322/

相关文章:

c - 插入排序 : order numbers over 2^32

c - 这两个指向 char 初始化的指针之间的区别

c - 可变参数列表 : possibility to collect them in variable?

C++11:可变参数模板函数参数的数量?

c++ - 无法从 'unsigned short [9]' 转换为 'char []'

c++ - 如何从 typedef 转换为其组成数据类型?

c++ - 如何区分左右键(CTRL 和 ALT)?

c - C语言中Hex转Integer的方法,不能小写!

C#/.NET 泛型和 Cdecl Varargs 错误?

c++ - 如何在自己的函数中最好地处理 Mat 中的不同数字格式