2015-07-19 58 views
0

的非const版本專營模板我有一個模板結構:與常量和另一個模板

template<typename T> 
struct A {...}; 

,我想專注與另一模板類型B

但是,我想使這個專業化適用於Bconst B版本。可能嗎?

我已經嘗試過這種做法:

template<typename T, typename Enable = void> 
struct A {...}; 

template<typename T, typename U> 
struct A<T, std::enable_if<std::is_same<T, B<U>>::value || std::is_same<T, const B<U>>::value, void>::type 
{ 
... 
} 

但它無法編譯,給我error: template parameters not deducible in partial specialization

+0

是'B'類型還是模板類型? – Jarod42

+0

只是一個想法發生了:你可以專注於'B'和'B const',在const版本中實現這個功能,並從那個派生另一個?如果這有效,你不需要處理sfinae tmp的東西。 – JorenHeit

回答

2

您可以爲is_B創建一個特徵,並用它:

template <typename T> struct is_BT : std::false_type {}; 
template <typename T> struct is_BT<B<T>> : std::true_type {}; 
template <typename T> struct is_BT<const B<T>> : std::true_type {}; 

template<typename T> 
struct A<T, std::enable_if_t<is_BT<T>::value>> 
{ 
// ... 
}; 

Live Demo

+0

'is_BT :: value'而不是'is_BT {}'? – Yakk

+0

@Yakk:所以它適用於不支持'constexpr'的編譯器。 – Jarod42

+0

接受這個答案。 Piotr_S提供了相同的解決方案,所以信用也給他:) – hweom

1
#include <type_traits> 

template <typename T> 
struct B {}; 

template <typename T> 
struct is_b : std::false_type {}; 

template <typename T> 
struct is_b<B<T>> : std::true_type {}; 

template <typename T> 
struct is_b<const B<T>> : std::true_type {}; 

template <typename T, typename Enable = void> 
struct A {}; 

template <typename T> 
struct A<T, typename std::enable_if<is_b<T>{}>::type> {}; 

DEMO

+0

爲了好玩,'template struct is_b :is_b {}'可以代替'const B '專業化。 – Yakk

0

我從評論中提出了我的建議。此解決方案不使用SFINAE或其他TMP技術。這比其他建議稍微簡單一點,所以我希望我不會誤解這個問題。

這個想法是,你只是專精兩次,兩個爲B<T>B<T> const的情況。爲了避免必須兩次實現這個類,你只需從const版本中派生非const的版本(以保持const正確性)。

#include <iostream> 

template <typename T> 
struct B {}; 

template <typename T> 
struct A 
{ 
    void foo() { std::cout << "Generic A\n"; } 
}; 

template <typename T> 
struct A<B<T> const> 
{ 
    // insert specialized functionality here 
    void foo() { std::cout << "B specialization\n"; } 
}; 

template <typename T> 
struct A<B<T>>: public A<B<T> const> 
{}; 


int main() 
{ 
    A<int>().foo(); // Generic A 
    A<B<int>>().foo(); // B specialization 
    A<B<int> const>().foo(); // B specialization 
} 

它假設你需要兩個專業化(非const和const)相同的實現。

+0

這確實是一個解決方案。然而,我的設計還沒有完成,我有一種感覺,我需要在const或非const版本中進行一些調整,這可以通過結構中額外的'std :: enable_if'來實現。這就是爲什麼我接受了具有特質的解決方案。不過,謝謝你的想法。 – hweom

+0

@hweom你仍然可以通過重新定義調整後的方法來做到這一點。但沒有苛刻的感覺,你做出了你的選擇;-) – JorenHeit