Можно ли смоделировать аргументы шаблона по умолчанию в частичных специализациях? - PullRequest
6 голосов
/ 16 марта 2012

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

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 Ответ

4 голосов
/ 16 марта 2012

Может быть, вы можете вставить различие в базовый класс:

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