Можно ли имитировать аргументы шаблона по умолчанию в частичных специализациях?

Аргументы шаблона по умолчанию могут использоваться для имитации псевдонимов для выражений сложного типа в объявлении шаблона. Например:

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>
    { ... };

Но по разным причинам (в том числе из-за желания избежать отдельного типа, который усложняет то, что я делаю), я надеюсь, что существует лучшее решение. Есть идеи?

6
задан Lightness Races with Monica 15 March 2012 в 21:49
поделиться