2010-04-22 31 views
3

C#有泛型函數類型,如Action<T>Func<T,U,V,...>C#式動作<T>,Func鍵<T,T>等C++ 0x中

用C++ 0x中的出現,並有模板的typedef的和可變參數模板參數的能力,這似乎應該是可能的。

我明顯的解決辦法是這樣的:

template <typename T> 
using Action<T> = void (*)(T); 

然而,這並不適應函子或C++ 0x中lambda表達式,除此之外,不會出現錯誤「expected unqualified-id before 'using'

編譯

我的下一個嘗試是可能使用boost ::功能:

template <typename T> 
using Action<T> = boost::function<void (T)>; 

這並不編譯或者,出於同樣的原因。

我唯一的其他想法是STL風格模板參數:

template <typename T, typename Action> 
void foo(T value, Action f) { 
    f(value); 
} 

但是,這並沒有提供一個強類型的解決方案,並且是唯一的模板函數內部相關。

現在,我會第一個承認我不是C++的人,我更喜歡認爲我是,所以很可能有一個明顯的解決方案,我沒有看到。

是否有可能在C++中擁有C#樣式的泛型函數類型?

+0

不,不可能。不完全的。他們是不同的語言。問題是最接近的近似值*,根據您的需求*。你是否需要類型擦除,所以具有相同簽名的每個函子都顯示爲相同類型?如果是這樣,你將不得不跳過一些環節,並失去一些效率。通常,這不值得,因爲由於模板和泛型之間的差異,通常不需要*。通常,但並非總是如此。你需要什麼?除了盲目地試圖在C++中模擬C# – jalf 2010-04-26 14:19:21

回答

6

我覺得語法應該是這樣的:

template <typename T> 
using Action = void (*)(T); 

我不能拿到編譯要麼,雖然(G ++ V4.3.2)。

一般的STL樣式函數模板在最嚴格的意義上並不是強類型的,但它是類型安全的,因爲編譯器將確保模板僅針對滿足函數所有要求的類型進行實例化。具體來說,如果Action不可用一個T類型的參數進行調用,則會出現編譯器錯誤。這是一種非常靈活的方法,因爲如果Action被實例化爲函數或實現operator()的某個類,則無關緊要。

老非的C++ 0x的解決方法失蹤模板的typedef是使用模板化的結構與嵌套的typedef:

template <typename T> 
struct Action { 
    typedef boost::function<void (T)> type; 
}; 

template <typename T> 
void foo(T value, typename Action<T>::type f) { 
    f(value); 
} 
1

GCC不支持尚未模板別名(見here)我不確定是否考慮了可變模板別名。我不認爲其他編譯器已經支持這個功能。

我只會使用std :: function或std :: function而不是Action或Func。

當然,你可以從std :: function中定義可變參數模板類Action或Func,但我沒有看到好處。

1

我不認爲泛型函數類型是直觀的C++,因爲C++模板與泛型不同。

C++的方式是使用函數對象 - 任何你可以把()之後,它是有意義的編譯器。這可以是一個函數指針,類別爲operator(),依此類推。這是有效的,因爲C++模板就像花式宏一樣,只要代碼對於替換類型有意義,你就可以。

C#泛型不能像那樣工作 - 它們更具限制性,可能是爲了改進錯誤消息(因爲獲取C++模板錯誤在輸出中非常詳細)。我不太瞭解C#泛型,但我認爲他們依賴於更像回調的東西,因此功能泛型的用處非常大。

相關問題