Аргументы шаблона по умолчанию могут использоваться для имитации псевдонимов для выражений сложного типа в объявлении шаблона. Например:
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>
{ ... };
Но по разным причинам (в том числе из-за желания избежать отдельного типа, который усложняет то, что я делаю), я надеюсь, что существует лучшее решение. Есть идеи?