我有一个C 类,其方法是模板以遵循可可的特征:
// A general data object
struct MyObject
{
// ... hold some data, parameters, ...
};
class MyOptimizationAlgorithm
{
// ...
public:
// An optimization function that uses a user-supplied
// callable to evaluate a data object:
template <class Callable> void optimize(MyObject o, Callable evaluator) {
// ... optimize, optimize, ...
auto value = evaluator(o);
// ... are we good enough yet?
}
};
在这里,MyOptimizationAlgorithm
类实现了优化算法。用户提供一个数据对象(双打向量,这里没有问题)和目标函数。此功能是优化算法所依赖的用户配置部分。例如,有效的可召唤者可以实现Ackley的功能,交叉托盘功能等。
该模式实际上是非常标准的:在C 中,可呼叫/谓词特征使我能够模板一种方法,以便我可以通过函数或std::function
。例如,
struct Ackley
{
double operator()(MyObject const& o)
{
return /* ackley() applied to the values in o */
}
};
MyOptimizationAlgorithm optimizer;
MyObject initialData;
// ... supply data,
// ... tune some parameters of the optimizer, then:
optimizer.optimize(initialData, Ackley());
// ... or:
optimizer.optimize(initalData, [](MyObject const& o) { /* ... */ });
我现在想用Swig为Python创建一个包装纸。当然,目标是在Python中创建评估器函数并将其传递给C 例程,例如:
def CrossInTray:
def __call__(self, obj):
# calculate the cross-in tray function.
optimzer = MyOptimizationAlgorithm()
initial_data = MyObject()
# ... again, setup, then:
optimizer.optimize(initial_data, CrossInTray())
我是Swig的新手。我收集到的是,我需要专门研究模板(使用%template
),并且需要创建导演(%director
)。我试图创建一个函子包装器,例如:
%inline %{
struct MyEvaluator
{
virtual double operator()(MyObject const& o) { return 0.0; }
virtual ~MyEvaluator() {}
};
%}
%feature("director") MyEvaluator;
%extend MyAlgorithm {
%template(runPredicated) optimize<MyEvaluator>;
}
我曾希望我可以在Python中创建函数的子类,并在其中定义__call__
并使用它,但是它只会调用MyEvaluator::operator()
,这是毫无意义的(并且是可以理解的,因为我将模板专用于使用MyEvaluator
)。
so:我需要添加到接口文件中,以利用python中的C 代码的可可特征?
这太通用了。如果您想将自己限制在std ::功能接口,例如
class MyOptimizationAlgorithm
{
// ...
public:
// An optimization function that uses a user-supplied
// callable to evaluate a data object:
template<typename T>
void optimize(MyObject o, std::function<T(MyObject const&)> evaluator) {
// ... optimize, optimize, ...
T value = evaluator(o);
// ... are we good enough yet?
}
};
可能的包装器看起来像
class MyOptimizationAlgorithm:
def `optimize<double>` as optimize(o: MyObject, evaluator: (o: MyObject)->float)
可以使用任何python功能来调用MyObject并返回浮子。问题中的python代码应该只是工作。
上面的包装器是pyclif(而不是swig)。