2012-03-15 39 views
5

默认模板参数可用于模拟模板声明中复杂类型表达式的别名。例如:是否可以模拟部分专业化中的默认模板参数?

template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type 
struct foo { ... X, Y, Z ... }; 

然而,部分特例不能有默认模板参数([C++11: 14.5.5/8]),所以这招不起作用。你可能会问自己,为什么在身体中的typedef不起作用,并且答案是别名需要位于班级体的范围之内,以便进行有条件的启用;例如:

template <typename T, typename Enable = void> 
struct bar; 

// Wishful thinking: 
template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type> 
struct bar <std::vector<X>, 
      typename enable_if< 
       some_condition<X, Y, Z> 
      >::type> 
    { ... }; 

我周围的工作方式是使用辅助类型:

template <typename X> 
struct bar_enabled { 
    typedef typename do_something_with<X>::type Y; 
    typedef typename some_other_thing_using<X, Y>::type Z; 
    static const bool value = some_condition<X, Y, Z>::value; 
}; 

template <typename X> 
struct bar <std::vector<X>, 
      typename enable_if_c< 
       bar_enabled<X>::value 
      >::type> 
    { ... }; 

但由于种种原因(其中包括想避免一个单独的类型,复杂化,我什么做),我希望有更好的解决方案。有任何想法吗?

+1

默认参数没有任何模拟。他们提供默认值。 – 2012-03-15 21:41:28

+3

为了记录,“专业化模板参数列表不应包含默认模板参数值”[C++ 11:14.5.5/8]' – 2012-03-15 21:42:27

+0

@LightnessRacesinOrbit,你的意思是指出这个问题没有'在C++ 11中改变了,还是其他的东西? – ajg 2012-03-15 21:54:00

回答

3

也许你能坚持的区别为一个基类:

template <typename X, typename Y, bool> 
struct BaseImpl    { /* ... */ }; 

template <typename X, typename Y> 
struct BaseImpl<X, Y, true> { /* ... */ }; 

template <typename X, typename Y = typename weird_stuff<X>::type> 
struct Foo : BaseImpl<X, Y, some_condition<X, Y>::value> 
{ 
    // common stuff 
};