Why does this template have an error in Xcode but not Visual Studio?

I get an error in Xcode when using templates in C ++. Can someone tell me what is wrong?

The first version reports an error in Xcode, but not in 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); } 

The second error has not. The difference lies in using the LengthT template parameter in the typedef template.

 // 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); } 
+4
source share
2 answers

The cause of the error is that the compiler does not know that graph_traits<Graph>::vertex_descriptor . Is it a static member or type? If it is a type, you should say the following:

 typename graph_traits<Graph>::vertex_descriptor 

The reason the compiler is not smart enough to understand this on its own is because LengthT is a template parameter. It can be anything, and therefore, when declaring a template, the compiler cannot determine what its value is, and typing is ambiguous.

+5
source

vertex_descriptor is a dependent type (it depends on the argument of the LengthT template), so you should use typename :

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

In the second example, the attribute of the template argument is deleted (a fixed type is used instead - int ), so there is no error.

A simpler way to reproduce this:

 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, as you know, is inconsistent in this regard and is "excellent" for developing non-portable template code.

+5
source

All Articles