2015-07-19 46 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