2012-06-29 19 views
0

有沒有一種方法可以要求模板類型具有屬性?在C++中鍵入鴨子的模板

例如:

template <typename T, typename U> 
void foo() 
{ 
    U a,b; 
    bool truthiness = T()(a,b); 
    if (truthiness) 
     // do something 
} 

那麼,如何將要求T已在operator()(U a, U b)定義,它返回一個特定類型的?這可能嗎? (我知道它在D中,但我不確定C++)。

ps。如果鴨子打字在這裏是錯誤的,讓我知道,我相信這是正確的,但我不確定。

+0

問題是,如果它沒有那個操作符,你想要發生什麼?不考慮語法錯誤,你會得到一個編譯器錯誤 - 你還想要什麼? – ildjarn

+0

這就是(概念)應該提供的(部分) - 一種直接的方式來指定模板可以被實例化的類型的需求。不幸的是,儘管做了很多工作,但沒有達到標準。 –

+1

查看SFINAE,這是專門爲此目的而設計的技術。 –

回答

2

通過簡單表達模板,您需要T有operator()(int, int)。如果沒有,它將不會編譯。

但是,如果你正在創建一個API並且想要通知用戶API他們已經通過了一個不兼容的類型,那麼你需要創建一個類型trait來檢測操作符,並且你可以專門化該函數來區分這個事實並創建一個static_assert來表明事實。

+0

這是遊戲開始的地方。模板需要的條件是不是*運算符()(int,int)存在,條件是表達式'T(1,2)'是有效的(實際上應該是'T()(1 ,2)'或類似的,我認爲這個問題有錯誤)。例如,運算符()(long(long))就足夠了。你需要決定你想要執行什麼,以及爲什麼,但通常情況下,根據所需的表達式記錄文件是要走的路,而不是根據你認爲某人可能實現的使這些表達式有效的函數。 –

4

考慮到你的意圖,你的語法是錯誤的。由於T是一種類型,因此T(1, 2)將使用雙參數構造函數構造類型爲T的臨時對象。如果你想叫T的operator ()你不得不вo像

T()(1, 2); 

假設通過一個臨時工程的目的打電話。

如果T沒有這樣的運算符(),則代碼將無法編譯。實際上,我認爲模板代碼的一個很大的好處是,只要語法有效(即您正在談論的鴨子打字),它就「起作用」,即不需要進一步限制它,因爲需要operator()出席。

當然,在我的例子中它可能是有意義的,因爲對於T = void (*)(int, int),代碼在語法上是有效的,但會導致通過空指針的函數調用。但是,這又是特定於我的代碼版本的,並且我不知道您要將運營商()應用於哪個類型的特定對象T

儘管如此,Boost庫有很多功能可以讓我們檢查這些屬性,並將它們用於模板元編程和/或靜態斷言中的分支。

+0

謝謝,我正在研究助推庫。如果你能回答更一般的問題,我已經稍微修改了這個問題。 –

+0

@AndrewSpott:我不確定boost是否提供瞭解決方案,但[this](https://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4f7c7a96f9afbe44/)提供了一個解決方案關閉解決方案請注意,如果'operator()'是私有的,C++ 03解決方案將無法編譯,因爲SFINAE無法用於檢測可訪問性。 –

0

如果您有權訪問decltype,則可以相對容易地推出自己的支票。

template <class T, class U> class check_same_type_t; 

template <class T> class check_same_type_t<T, T> { }; 

template <class T, class U> 
void foo() 
{ 
    U a,b; 
    check_same_type_t<bool, decltype(T()(a, b))> check; 
    bool truthiness = T()(a,b); 
    if (truthiness) ; 
     // do something 
} 

,可實現以下:

struct A { 
    bool operator()(int, int) { return true; } 
}; 

struct B { 
    int operator()(int, int) { return 1; } 
}; 

int 
main() 
{ 
    foo<A, int>(); // will compile 
    foo<B, int>(); // won't compile 

} 

只要確保這個你真正想要的。 強制通用算法使用特定類型可能會回來咬你。如果一個類型可以隱式轉換爲bool,爲什麼它在你的條件下使用並不令人滿意?