Почему этот шаблон имеет ошибку в XCode, но не в Visual Studio? - PullRequest
4 голосов
/ 30 июля 2010

Я получаю ошибку в XCode при использовании шаблонов в C ++. Может кто-нибудь сказать мне, что не так?

Первая версия сообщает об ошибке в Xcode, но не в Visual Studio.

// Version 1: Error in Xcode, but not Visual Studio
template<typename LengthT, typename VertexT> 
int MyGraphAlgorithm(...arguments omitted...)
{
  using namespace boost;

  typedef property<vertex_distance_t, LengthT> VertextProperties_t;
  typedef adjacency_list<vecS, vecS, directedS, VertextProperties_t> Graph;
  // In next line Xcode reports: "error: expected `;' before 'vertexInitial'"
  graph_traits<Graph>::vertex_descriptor vertexInitial(100);
}

Второй не имеет ошибки. Разница заключается в использовании параметра шаблона LengthT в шаблонном определении типа.

// Version 2: No error in Xcode or Visual Studio
template<typename LengthT, typename VertexT> 
int MyGraphAlgorithm(...arguments omitted...)
{
  using namespace boost;

  // In the following line, LengthT has been changed to int
  typedef property<vertex_distance_t, int> VertextProperties_t;
  typedef adjacency_list<vecS, vecS, directedS, VertextProperties_t> Graph;
  graph_traits<Graph>::vertex_descriptor  vertexInitial(100);
}

Ответы [ 2 ]

5 голосов
/ 30 июля 2010

Причина ошибки заключается в том, что компилятор не имеет ни малейшего представления о том, что graph_traits<Graph>::vertex_descriptor равно . Это статический член или тип? Если это тип, то вы должны сказать так:

typename graph_traits<Graph>::vertex_descriptor

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

5 голосов
/ 30 июля 2010

vertex_descriptor является зависимым типом (зависит от аргумента шаблона LengthT), поэтому вы должны использовать typename:

typename graph_traits<Graph>::vertex_descriptor vertexInitial(100);

Во втором примере зависимость от аргумента шаблонаудаляется (вместо этого используется фиксированный тип - int), поэтому ошибки не возникает.

Более простой способ воспроизвести это:

template<class T> struct A { typedef T type; };
template<class T> struct B { 
    A<T>::type t1; // wrong, works with VS but not with conforming compilers
    typename A<T>::type t2; // correct
};

Известно, что Visual Studioнесоответствующий в этом отношении и "отлично" для разработки непереносимого шаблонного кода.

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