Доступ к вложенным параметрам шаблона без аргументов шаблона - PullRequest
2 голосов
/ 10 ноября 2011

У меня такая ситуация:

template<unsigned int N>
class Base
{
public:
    Base(){}
    int myint[N];
};

template<unsigned int M>
class BaseWrapper : Base<M>
{
public:
    BaseWrapper(){}
};

template<typename T>
class User
{
public:
    User(){}
    //int myint[T::N]; //How to statically allocate using M or N from above?
};

int main(void)
{
    User<BaseWrapper<10> > myuser;
    // Do something with User::myint here.
}

Я хочу иметь возможность использовать параметр не-типа аргумента шаблона для User для статического размещения данных в классе User. Я знаю, что могу использовать параметры шаблона шаблона для создания BaseWrapper<M> внутри User, но это не мой предпочтительный подход. Есть ли простые способы сделать это?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 10 ноября 2011

Добавьте static const unsigned int Size = N; в свой класс.

Пример:

template<unsigned int N>
class Base
{
public:
    Base(){}
    int myint[N];
    static const unsigned int Size = N;
};

Тогда N доступно как T::Size в вашем User классе.

2 голосов
/ 10 ноября 2011

Решение 1

Объявите данные статического члена const как:

template<unsigned int M>
class BaseWrapper : Base<M>
{
public:
    static const unsigned int size = M; //add this line!
    BaseWrapper(){}
};

Затем используйте это как T::size в User классе:

template<typename T>
class User
{
public:
    User(){}
    int myint[T::size];  //you can do this!
};

Решение 2

Или, если вы не можете добавить size в качестве члена (по какой-либо причине), вы можете использовать этот подход как:

template<typename T> struct get;

template<unsigned int N> 
struct get< BaseWrapper<N> > //partial specialization!
{
     static const unsigned int size = N;
};


template<typename T>
class User
{
public:
    User(){}
    int myint[get<T>::size];  //get the size!
};
0 голосов
/ 10 ноября 2011

Самый простой способ, о котором уже упоминали другие, - это добавить статический член к Basewrapper, который инициализируется в N.

Однако, если по какой-то причине вы не можете изменить User, есть также способ получить N:

template<typename T> struct get_N;
template<unsigned int N> struct get_N<Basewrapper<N> > { unsigned int const value = N; };

Теперь в вашем шаблоне User вы можете просто написать get_N<T>::value.

Одним из преимуществ этого является то, что вы можете адаптироватьлюбой тип после факта, не касаясь его определения, поэтому, если вы когда-либо захотите создать экземпляр User для чего-либо, кроме Basewrapper, скажем, для Newbasewrapper, вы просто добавляете строку

template<unsigned int N> struct get_N<Newbasewrapper<N> > { unsigned int const value = N; };

илиесли Newbasewrapper принимает какой-либо тип в качестве аргумента шаблона и предоставляет значение N в качестве статического члена const,

template<typename T> struct get_N<Basewrapper<T> > { unsigned int const value = Basewrapper<T>::N; };
0 голосов
/ 10 ноября 2011

Вы можете выставить параметр шаблона как статическую переменную-член класса:

template<unsigned int M>
class BaseWrapper : Base<M>
{
public:
    static const int counter = M;
    BaseWrapper(){}
};

Тогда вы можете использовать этот статический член в вашем User классе:

template<typename T>
class User
{
public:
    User(){}
    int myint[T::counter];
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...