2011-09-19 20 views
3

我想爲可以處理多種數據類型的Matlab編寫一個C++ mex函數。 Matlab給我一個mxArray*,從中我可以檢索數據的void*,以及一個mxClassID告訴我數據類型。所以,我可以這樣做:C++解碼void指針很好用於Matlab mex

void *data = mxGetData(mxarray); 
switch (mxGetClassID(mxarray)) { 
    case mxDOUBLE_CLASS: 
    my_function(static_cast<double *>(data)); 
    ... 

my_function是模板化,所以這很好地處理不同的數據類型。但它仍然是非常煩人的需要有這個開關的每一個可能的my_function1my_function2

到目前爲止,我提出的解決方案是使用功能的方法,並有一個方法,接受函子:

template <typename ReturnType, typename FunctorType> 
ReturnType mxarr_apply(const mxArray *inarr, FunctorType functor) { 
    void *data = mxGetData(inarr); 
    switch (mxGetClassID(inarr)) { 
    case mxDOUBLE_CLASS: 
     return (ReturnType) functor(static_cast<double *>(data)); 
    ... 

這樣我可以把我的邏輯函子(帶operator()模板),而不必一遍遍重新開關。

但我想知道是否有其他方法嗎?在Java中,我認爲我只需要一個將mxClassID直接轉換爲class引用的函數,然後該函數可以在運行時用於實例化類型,但這似乎不是C++中的一個選項。

回答

2

你是對的。 C++無法在運行時獲得類引用。你必須至少寫一次開關。

+1

+1 ..並且最好是最多一次 – stijn

+0

非常感謝。而爲了只寫一次開關,仿函數的方法就行了嗎?或者還有其他選擇嗎?處理輸出時,這種設置會變得特別痛苦。在許多情況下,我發現我僅限於基於副作用的輸出。 – Chinasaur

0

如果你面對需要寫你可能想要麼隱藏它的邏輯到工廠多個交換機,這將是給定類型

void *data = mxGetData(mxarray); 
functor func = FunctorFactory::Get(mxGetClassID(mxarray)); 
func (reinterpret_cast<double*>(data)); 

或簡單地創建一個地圖(最好是無序返回正確的函子或一個哈希)的類型到函子。

void *data = mxGetData(mxarray); 
functor func = functorMap[mxGetClassID(mxarray)]; // need to check for key availability 
func (reinterpret_cast<double*>(data)); 
+0

謝謝,有趣的建議。對於仿函數工廠模式,仿函數的返回類型是固定的,對吧?我使用模板化的operator()'做了我的函子,因此通常可以按類型獲取正確的函數。 – Chinasaur

+0

我認爲static_cast對於這種情況是可以的;我將我的例子從C風格改爲static_cast。 – Chinasaur