2014-09-27 2 views
-1

Учитывая класс шаблона:Как вы можете использовать типы, определенные в шаблоне в C++?

template<class T, class U> 
    struct myList { 
    typedef T head; 
    typedef U next; 
    }; 

class nullList {}; 

Можно составить список классов, например

myList<int, myList<string, myList<short, nullList> > >; 

Я пытаюсь использовать приведенный выше список, чтобы создать класс шаблона, который обрабатывает только классы в списке. В приведенном выше примере мой класс будет обрабатывать ints, string и shorts (например, печатать их на консоли).

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

template<class T, class U> 
class myClass { 
    ... 
}; 

терпит неудачу, потому что MyClass принимает только один параметр шаблона, и что MyList т.е.

myClass<myList> 

Но если я пытаюсь использовать

template<typename l> 
class myClass { 
    l.head foo;// cannot refer to type member 'head' in 'myList<int, nullList>' with '.' 
} 

Технически myList.head должен быть класс, не так ли? Как я могу использовать эту информацию?

+1

Переименуйте свой шаблон, например. 'mylist', чтобы избежать конфликтов и путаницы с' std :: list'. И, пожалуйста, прочитайте хорошую [C++ programming] (http://www.stroustrup.com/programming.html) книгу. –

+0

Вы должны объяснить, почему вы считаете, что шаблон списка должен иметь два параметра шаблона. Я предполагаю, что он должен иметь только один (тип данных внутри элементов списка). Или ваше имя 'myList' запутывает: вы * не * имеете дело с любым списком. –

+0

@BasileStarynkevitch Потому что это список типов, а не список значений. Такой шаблон списка довольно распространен в мета-программировании шаблонов, который, как я полагаю, является тем, чему в настоящее время занимается ОП. – sepp2k

ответ

2

Оператор . обращается к членам объектов. l не объект - это класс. Для доступа к статическим членам классов используется оператор ::. Когда член, к которому вы обращаетесь, является типом, а класс, к которому вы обращаетесь, является параметром шаблона, для синтаксических причин вам также понадобится ключевое слово typename. Так ваш будет:

template<typename l> 
class myClass { 
    typename l::head foo; 
} 

Если все, что вы хотите, чтобы напечатать значения данного типа, и вы не заинтересованы в создании объектов с членами этого типа, вы могли бы просто определить статическую функцию, которая принимает тип, аргумент:

template<typename l> 
class myClass { 
    public: 
    static void print(typename l::head foo) { 
     std::cout << foo << std::endl; 
    } 
}; 

на самом деле в этом случае, если вы только рассмотреть голову списка, вам не нужен класс вообще и просто не мог сделать:

template<typename l> 
void print(typename l::head foo) { 
    std::cout << foo << std::endl; 
} 

Однако вы» ll (probab ly) нужен класс, как только вы начинаете принимать во внимание хвост списка.

+0

Не должно ли второе вхождение 'typename' быть' typedef'? –

+0

@BasileStarynkevitch Нет. Мы объявляем переменную, а не typedef. Тип переменной - 'l :: head', а ее имя -' foo'. – sepp2k

+0

Но почему бы просто не использовать просто 'l :: head foo;'? –