what's the right way to export template function from c++ into python using boost.python? Here is the code:
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>);
And usage:
print GetValue("width")
Boost.Python.ArgumentError: Python argument types in
GetValue(ConfigManager, str)
did not match C++ signature:
GetValue(ConfigManager {lvalue}, std::string, int)
What's wrong?
The Export Template function allows a user to define and save an export configuration for future use. It is recommended that the system administrator assists users in creating advanced export templates, especially those that export data from multiple repositories.
Templates are powerful features of C++ which allows us to write generic programs. We can create a single function to work with different data types by using a template.
You can export the template that was used to deploy existing resources. The template you get is exactly the one that was used for deployment. Select the resource group you want to export.
A C++ template is a powerful feature added to C++. It allows you to define the generic classes and generic functions and thus provides support for generic programming. Generic programming is a technique where generic types are used as parameters in algorithms so that they can work for a variety of data types.
You should read the relevant Boost documentation regarding default arguments. I'll summarize below.
The problem here is that default arguments are used when calling functions in C++. Get rid of them and you'll see the problem from Python's perspective:
// 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
The fundamental issue is that function types don't carry default argument information. So how can we simulate it? Essentially, by overloading:
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
A maintenance hassle. Luckily, Boost makes this easy:
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
The macro also exists for class members. This is in the documentation, if any of it is unclear.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With