2017-02-15 12 views
2

Мне нужно получить 2 типа параметров для моего класса: T1, который является классом с шаблоном, и T2, который является параметром для шаблона T1 ,Вложенные шаблоны (например, шаблон <typename T <typename templateArgumentFor_T >>)

В моем случае тип Вершина (есть 2, один наследуется от другого), а тип данных хранит вершину (имя/идентификатор в моем случае).

Я хочу, чтобы иметь возможность написать что-то вроде этого:

template < typename VertexType < typename VertexIDType > > 

(который дал мне ошибку: C2143 ошибка синтаксиса: отсутствующий «» перед «<»)

Так что мой класс было бы что-то вроде этого: (. 'List' мой (не ЗППП) реализация для связанного списка)

class Graph 
{ 
public:  
    Graph(const List<VertexType<VertexIDType>>& verticesList); 
    VertexType<VertexIDType>& getVertexByID(const VertexIDType& ID) const; 

private:  
    List<VertexType<VertexIDType>> vertices; 
}; 

Я также попытался template <typename VertexType, typename VertexIDType> , но потом я получил ошибку в функции Graph(const List<VertexType<VertexIDType>>& verticesList); (C2947 ожидая '>' прекратить шаблонный аргумент-список, найденный '<')

и этот template < typename VertexType < template <typename VertexIDType> > >

(который также дал мне ошибку C2143)

Я действительно такой человек, который пытается сам все выяснить, но этот получает разочарование. Я не мог найти ответ, который я понял, если/как реализовать в моем коде. Я закончил курс ООП (C++). У меня есть опыт работы с шаблонами. Я написал шаблоны, которые успешно получили 1 или 2 аргумента, но ничего подобного.

Пожалуйста, помогите мне решить эту проблему, предпочтительно настолько элегантно, насколько это возможно :)

Спасибо.

ответ

3

Вы можете использовать параметры шаблона шаблона:

template <template <typename> class VertexType, typename VertexIDType> 
class graph; 

graph<MyVertexType, MyVertexIDType> //usage 

В качестве альтернативы вы можете взять только тип и извлечь тип ID в частичной специализации:

template <typename Vertex> 
class graph; 

template <template <typename> class VertexType, typename VertexIDType> 
class graph <VertexType<VertexIDType>> { 
    //... 
}; 

graph<MyVertexType<MyVertexIDType>> //usage 
+0

Большое спасибо! –

1

ответ TartanLlama является хорошим один для вопрос, который вы задали, но вы можете немного изменить свой подход. Если вам требуется, чтобы VertexType необходимо определить ЬурейиЙ VertexIDType, то вы можете написать:

template <class VertexType> 
class Graph 
{ 
public:  
    Graph(const List<VertexType>& verticesList); 
    typedef typename VertexType::VertexIDType VertexIDType; 
    VertexType& getVertexByID(const VertexIDType& ID) const; 

private:  
    List<VertexType> vertices; 
}; 

Обратите внимание на typename в ЬурейеМ для VertexIDType. Необходимо сказать «это имя должно быть быть типом, а не переменной».

Предполагая, что ваш текущий VertexType является шаблонный на VertexIDType:

template <classname VertexIDType> 
struct VType1 { 
    double stuff; // Or whatever you have in your vertex 
}; 

Вы должны были бы изменить его на:

template <classname VertexIDType> 
struct VType1 { 
    double stuff; 
    typedef VertexIDType VertexIDType; // Provide a typedef for VertexIDType. 
}; 

Это аналогично подходу стандартная библиотека принимает, где каждый тип, который представляет собой контейнер имеет typedef для value_type и т. д.

+0

Можете ли вы подробнее описать определение типа typedef? Я не совсем понял синтаксис. Что означает первый «VertexIDType»? Как бы это выглядело в определении «VertexType» (где, я думаю, вы ожидаете, что это будет, таким образом, «::»)? Что означает второй «VertexIDType»? Кроме того, в моем коде «VertexIDType» не определен в «VertexType». Он просто обозначается как шаблонный аргумент. Это не класс. Он обозначает int, long, char, string и т. Д. Или нестандартные типы (классы), если это понадобится в будущем. –

+0

Итак, идея состоит в том, чтобы изменить 'VertexType' так, чтобы в нем был определен' VertexIDType' *. Помогло ли мое редактирование? –

+0

@DrorFelman: VertexIDType аргумент шаблона для VertextType? Если это так, это делает его еще проще. –