2015-02-08 78 views
0

我有兩個模板參數制約功能模板參數對某些類型的

template<class X, class Y> 
bool fun(X x, Y y) { ... } 

我需要第二個參數限制對以下兩種情況下的函數:int yvector<int> const& y。如果我嘗試static_assert

static_assert(std::is_same<int, Y>::value || 
       std::is_same<std::vector<int> const&, Y>::value, 
       "unsupported Y class"); 

那麼下面不會因爲Y被推斷爲vector<int>而不是vector<int> const&編譯

X x; 
std::vector<int> y; 
fun(x, y); 

有沒有辦法按我想要的方式限制Y?

PS:當然,我可以撥打fun<X, vector<int> const&>(x, y)但我希望自動類型扣除工作。或者我可以複製和粘貼並分別具有兩個功能,但它是一個具有相同主體的長功能,我一直在更改,所以我不喜歡同步兩個副本。

回答

0

這聽起來像你希望能夠在任何的隱式轉換爲intconst std::vector<int>&通過,但你想要的實際參數類型爲intconst std::vector<int>&,你不想重複執行。那麼,這樣做:

template <class X, class Y> 
bool actual_fun(X x, Y y) { 
    // actual implementation 
} 

template <class X> 
bool fun(X x, int y) { 
    return actual_fun<X, int>(x, y); 
} 

template <class X> 
bool fun(X x, const std::vector<int>& y) { 
    return actual_fun<X, const std::vector<int>&>(x, y); 
} 

(你可能希望在namespace detail或諸如此類的東西來包裝actual_fun

0

Y永遠不會推斷爲const vector<int>&。只有在用戶明確提供該類型時纔會發生這種情況。

X x; 
std::vector<int> y; 
fun(x, y); // Y deduced as std::vector<int> 
fun<X, const std::vector<int>&>(x, y); // Y deduced as const std::vector<int>& 

所以,如果你不希望類型被明確使用,你可以static_assert與預期類型:

static_assert(std::is_same<int, Y>::value || 
       std::is_same<std::vector<int>, Y>::value, 
       "unsupported Y class"); 

但是,如果你想連處理的情況下調用者提供類型明確,那麼你要使用std::decay

using dY = typename std::decay<Y>::type; 

這將刪除const&預選賽。然後,你可以既做你的靜態斷言:

static_assert(std::is_same<int, dY>::value || 
       std::is_same<std::vector<int>, dY>::value, 
       "unsupported Y class");