2017-09-21 37 views
0

我有一個C++類與被模板化跟隨可調用性狀的方法,包括:如何使用swig for Python來包裝跟隨可調用特徵的模板化函數?

// 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++中,可調用/謂詞特徵允許我模板化一個方法,以便可以傳遞一個Functor或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()) 

我是新來痛飲。我收集到我需要專門化模板(使用%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)。

所以:我需要什麼添加到接口文件儘量使用C++代碼在Python中調用特質?

+0

的性狀可以從未使用Python實現,可以實現'%模板(runPredicated)優化;'是模板實例,在實例化點,'MyEvaluator'必須已知。你可以很容易做到在'C定義的接口++',在Python實現這一點,並在C++中使用,甚至在C++程序,請參見https://stackoverflow.com/questions/9040669/how-can-i-implement -ac級合蟒-待稱爲逐C/9042139 –

回答

0

這有點過於通用。如果你想限制自己的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並返回一個float被調用。問題中的Python代碼應該正常工作。

上面的包裝紙是PyCLIF(而不是SWIG)。

相關問題