Что делает этот «декларатор недействительным»? C ++ - PullRequest
5 голосов
/ 23 марта 2010

У меня есть шаблон Vertex в vertex.h. Из моего графика.h:

20 template<class edgeDecor, class vertexDecor, bool dir>
21 class Vertex;

, который я использую в своем шаблоне Графа.

Я успешно использовал шаблон Vertex в своем графике, возвращаю указатели на вершины и т. Д. Теперь я впервые пытаюсь объявить и создать экземпляр объекта Vertex, и gcc сообщает мне, что мой «объявлений» есть недействительным'. Как это может быть?

81 template<class edgeDecor, class vertexDecor, bool dir>
82 Graph<edgeDecor,int,dir> Graph<edgeDecor,vertexDecor,dir>::Dijkstra(vertex s, bool print = false) const
83 {
84    /* Construct new Graph with apropriate decorators */
85    Graph<edgeDecor,int,dir> span = new Graph<edgeDecor,int,dir>();
86    span.E.reserve(this->E.size());
87
88    typename Vertex<edgeDecor,int,dir> v = new Vertex(INT_MAX);
89    span.V = new vector<Vertex<edgeDecor,int,dir> >(this->V.size,v);
90 };

И gcc говорит:

graph.h: In member function ‘Graph<edgeDecor, int, dir> Graph<edgeDecor, vertexDecor, dir>::Dijkstra(Vertex<edgeDecor, vertexDecor, dir>, bool) const’:
graph.h:88: error: invalid declarator before ‘v’
graph.h:89: error: ‘v’ was not declared in this scope

Я знаю, что это, вероятно, еще один вопрос, но я буду признателен за любую помощь.

Ответы [ 3 ]

4 голосов
/ 23 марта 2010

Вероятно, должно быть

Vertex<edgeDecor,int,dir> v = new Vertex(INT_MAX);

, потому что вы объявляете экземпляр Vertex.typename Ключевое слово действительно только в списке параметров шаблона.

Спасибо Абхай и outis за указание на допустимое использование keyword вне списка параметров шаблона.

После еще одного взгляда на кодна ум приходит множество других вещей:

  1. Как указал Майк Динсдейл , здесь вам не хватает параметров шаблона: new Vertex(INT_MAX);.Вместо этого попробуйте Vertex<edgeDecor,int,dir>.
  2. Вы назначаете указатель на экземпляр класса.Если вы создаете его в стеке, оно должно выглядеть примерно так:

    Vertex v (INT_MAX);

При создании в куче v должен быть указательтип:

Vertex<edgeDecor,int,dir>* v = new Vertex<edgeDecor,int,dir>(INT_MAX);
1 голос
/ 23 марта 2010

Игорь прав. Что касается следующей ошибки:

graph.h:88: error: expected type-specifier before ‘Vertex’ 

... вам, вероятно, нужно сказать:

Vertex<edgeDecor,int,dir> v = new Vertex<edgeDecor,int,dir>(INT_MAX);
0 голосов
/ 23 марта 2010

Как уже говорилось, это проблема неуместного typename первого.

Некоторые примеры:

template <class T>
struct MyClass
{
  struct Foo { static int MBar; };
};

template <>
struct MyClass<int> { static int Foo; };

Использование MyClass:

template <class T>
void useMyClass(T t)
{
  MyClass<T> c;
}

Нет необходимости в typename, потому что нет никакой двусмысленности, компилятор знает, что MyClass должен быть здесь типом.

template <class T>
void useFoo(T t)
{
  typename MyClass<T>::Foo f;
}

Нам необходимо устранить неоднозначность, поскольку компилятор заранее не знает, будет ли символ Foo типом, методом или атрибутом. Действительно, если T == int этот код ошибочен, поскольку Foo будет представлять атрибут static вместо struct!

void useFoo(int t)
{
  int f = MyClass<int>::Foo;
}

void useFoo(float t)
{
  float f = MyClass<float>::Foo::MBar;
}

Здесь typename не требуется: так как компилятор знает все типы в списке параметров шаблона, он может создать экземпляр класса шаблона для MyClass<int> и MyClass<float>, а для обычного класса - изнутри каждый экземпляр (и, в частности, что представляет каждый символ).

template <class T>
void useBar(T t)
{
  int i = typename MyClass<T>::Foo::MBar;
}

Еще раз нам нужно typename, потому что Foo - это тип, и компилятор должен это знать.

Если вы на самом деле не понимаете, не волнуйтесь. Ключевые слова typename и template иногда появляются в необычных местах в универсальном коде: просто подождите, пока начнется ошибка компилятора, вы скоро запомните тип ошибок и исправите их в мгновение ока.

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