Можете ли вы частично специализировать частичную специализацию класса на c ++ - PullRequest
0 голосов
/ 07 мая 2020

У меня вопрос об иерархии частичной специализации шаблонов с c++-11. Я читал https://en.cppreference.com/w/cpp/language/partial_specialization, но не могу понять, как подробности работают с методами частично специализированных классов шаблонов.

У меня есть класс, который выглядит как

template <typename T, int N, int D, bool b>
class ClassA {
public:
T foo( std::array<T,N> const& x );
T bar( std::array<T,D> const& y );
protected:
/* some member variables */
std::array<T,N> var1;
std::array<T,D> var2;
};

Если b ложно, то у меня есть частичная специализация для всех T,N,D

template <typename T, int N, int D>
class ClassA<T,N,D,false> {
public:
T foo( std::array<T,N> const& x ) const { /* stuff for all T,N,D */ };
T bar( std::array<T,D> const& y ) const { /* stuff for all T,N,D */ };
};

Если b=true, то у меня есть частичная специализация для foo, которая работает для всех T, N, D, но не для bar.

template <typename T, int N, int D>
class ClassA<T,N,D,true> {
public:
T foo( std::array<T,N> const& x ) const { /* stuff that works for all T,N,D */ };
// Can't define bar yet, don't have sufficient information on D.
// T bar( std::array<T,D> const& y ) const { /* Don't know this yet */ };
};

, а для bar, у меня есть частичные специализации для D = 1,2,3,4 (которые являются единственными значениями D, которые я хочу поддерживать) .

template <typename T, int N>
class ClassA<T,N,1,true> {
public:
// Don't want to define foo again. want to use the definition from the b = true specialization
// T foo( std::array<T,N> const& x ) const { /* This was defined in the one parameter specialization */ };
T bar( std::array<T,1> const& y ) const { /* stuff that works for all T,N */ };
};

Мой вопрос: будет ли специализация для D=1 иметь специализацию для b = true? Применяются ли специализации вложенно? Т.е. частичная специализация по 2 параметрам может использовать отсутствующие определения функций, которые были определены в специализации по одному параметру? Или мне нужно скопировать и вставить определение foo в четыре специализации с двумя параметрами?

Для деталей, все эти методы полагаются на использование переменных-членов ClassA, иначе я бы разбил их на простые функции.

Любая помощь приветствуется.

1 Ответ

1 голос
/ 08 мая 2020

ClassA<T,N,1,true> более специализирован, чем ClassA<T,N,D,true>, поэтому это новый класс, который нужно определять с нуля. Вот почему я сам посмотрел на новые языковые функции, называемые if constexpr и требующие (концепций): это изменит ваш взгляд на вещи

template <typename T, int N, int D, bool b>
class ClassA
{
public:
T foo( std::array<T,N> const& x )
{
    if constexpr ( !b )
        // do something
    else
        // do something else (only the active statement will generate errors)
}

template <class=void>// allow the requirement below
requires !b || (D >= 1 && D <= 4)// this line can completely remove bar if you need
T bar( std::array<T,D> const& y )
{
    if constexpr ( !b )// no run time checking
        // do something
    else
        if constexpr ( D == 1 )
            // do something
        else if ( D == 2 )// also constexpr
            // do something
        else if ( D == 3 )
            // do something
        else if ( D == 4 )
            // do something
        else
            // non specialized code or
            static_assert(false);// compile time error if you want to get ride of the requires
}

protected:
/* some member variables */
std::array<T,N> var1;
std::array<T,D> var2;

};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...