Синтаксис для специализации вложенного шаблона класса

Я пытаюсь выяснить правильный синтаксис для явной специализации вложенного шаблона класса. Следующий код будет лучше иллюстрировать:

struct Column_Major;
struct Row_Major;

template<size_t rows, size_t cols, typename T, typename Allocator>
class Matrix
{

/* bunch of members */
template <typename storage = Column_Major>
class Iterator
{
/* bunch of members */
};
};

Я хотел бы написать явную специализацию для template <> class Matrix<...>::Iterator<Row_Major, но синтаксис ускользает от меня. У меня есть подозрение, что невозможно явно специализировать класс Iterator без явной специализации содержащего его класса Matrix. Но я был бы очень рад, если бы был способ сделать это.

я знаю я мог сделать класс Iterator отдельным классом, не являющимся членом класса Matrix, но имея вложенные классы как таковые, я получаю полный доступ к параметрам шаблона и элементам данных класса Matrix, что упрощает работу. Я знаю, что мог бы обойти это, если мне нужно, но сначала я хотел бы исследовать и понять возможности для вложенного подхода.

Спасибо,
Шмуэль

10

Решение

Для явной специализации вам нужно специализировать внешний класс, прежде чем внутренний, вы можете см этот вопрос например.

Существует обходной путь, который использует частичную специализацию:

template<size_t rows, size_t cols, typename T, typename Allocator>
class Matrix
{

//                           Notice the additionnal dummy parameter
//                                       vvvvvvvvvvvvv
template <typename storage = Column_Major, bool = true>
class Iterator
{
};

// Specialization
template <bool dummy>
class Iterator<Row_Major, dummy>
{
};
};
14

Другие решения

Вы можете сделать ответ Synxis (используя фиктивный фиктивный параметр) еще более чистым с C ++ 11:

/// template <typename X>, not needed for the example
struct Outer
{
private:
template <typename A, typename D = void>
struct Inner
{
Inner()  { cout << "default" << endl; }
};
template <typename D>
struct Inner<int,D>
{
Inner()  { cout << "int" << endl; }
};
public:
template <typename T>
using  Nested = Inner<T>;
};

Преимущество этого улучшения состоит в том, что подпись Nested имеет только один параметр шаблона, который, я думаю, поможет, если вы хотите правильно сопоставить его в метапрограммировании шаблонов.

1

Я удивлен, что параметр шаблона для вложенного класса не является параметром родительского класса.

Вложенный класс может использовать параметры шаблона родителя, и это более тесно связывает вложенный класс с родителем. Ваше использование слова итератор предполагает, что это хорошо, итератор наверняка перебирает тот же тип, что и родительский?

Я бы сделал это так:

template <class T>
class Outer
{
public:
class Inner
{
void Fn( T in )
{
}
};
};

// specialisation
void Outer<double>::Inner::Fn( double in )
{

}
0
По вопросам рекламы [email protected]