c-导出模板功能

使用boost.python将模板函数从c导出到python的正确方法是什么?这是代码:

template<typename T>
T getValue(const std::string &key, const T &defaultValue = T()) {}

// Export into some python class:
class_<ConfigManager>(...)
.def("GetValue", getValue<int>)
.def("GetValue", getValue<float>)
.def("GetValue", getValue<std::string>);

和用法:

    print GetValue("width")
Boost.Python.ArgumentError: Python argument types in
    GetValue(ConfigManager, str)
did not match C++ signature:
    GetValue(ConfigManager {lvalue}, std::string, int)

怎么了?

解决方法:

您应该阅读有关默认参数的Boost documentation.我将在下面总结.

这里的问题是在C中调用函数时会使用默认参数.摆脱它们,您将从Python的角度看到问题:

// this function *must* be called with two parameters
template<typename T>
T getValue(const std::string &key, const T &defaultValue) {}

class_<ConfigManager>(...)
.def("GetValue", getValue<int>) // two arguments!
.def("GetValue", getValue<float>) // Python has no idea about the defaults,
.def("GetValue", getValue<std::string>); // they are a C++ feature for calling

基本问题是函数类型不携带默认参数信息.那么我们如何模拟它呢?本质上,通过重载:

template<typename T>
T getValue(const std::string &key, const T &defaultValue) {}

template<typename T>
T getValueDefault(const std::string &key)
{
    // default available in C++,
    // transitively available in Python
    return getValue(key);
}

class_<ConfigManager>(...)
.def("GetValue", getValue<int>) // two arguments
.def("GetValue", getValueDefault<int>) // one argument
// and so on

维护麻烦.幸运的是,Boost使这变得容易:

template<typename T>
T getValue(const std::string &key, const T &defaultValue) {}

// creates utility class x, which creates overloads of function y,
// with argument count as low as a and as high as b:
// BOOST_PYTHON_FUNCTION_OVERLOADS(x, y, a, b);

BOOST_PYTHON_FUNCTION_OVERLOADS(getValueIntOverloads, getValue<int>, 1, 2);

class_<ConfigManager>(...)
.def("GetValue", getValue<int>, getValueIntOverloads()) // one or two arguments

// and so on

该宏也适用于班级成员.如果尚不清楚,则在文档中.

上一篇:内部的速度模板和Java代码


下一篇:JavaScript模板仅对将小项目插入DOM有用吗?