为什么这个模板在Xcode中有错误而在Visual Studio中没有?

gau*_*256 4 c++ xcode templates visual-c++

在C++中使用模板时,我在Xcode中遇到错误.谁能告诉我有什么问题?

第一个版本在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);
}
Run Code Online (Sandbox Code Playgroud)

第二个没有错误.不同之处在于模板化typedef中模板参数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);
}
Run Code Online (Sandbox Code Playgroud)

Geo*_*che 5

vertex_descriptor是一个依赖类型(它取决于模板参数LengthT),因此你必须使用typename:

typename graph_traits<Graph>::vertex_descriptor vertexInitial(100);
Run Code Online (Sandbox Code Playgroud)

在第二个示例中,删除了对模板参数的依赖性(使用固定类型 - 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
};
Run Code Online (Sandbox Code Playgroud)

已知Visual Studio在这方面不合格,并且对于开发非可移植模板代码而言"很棒".


wil*_*ell 5

究其原因,错误是编译器不知道什么graph_traits<Graph>::vertex_descriptor .它是静态成员还是类型?如果它是一种类型,那么你必须这样说:

typename graph_traits<Graph>::vertex_descriptor
Run Code Online (Sandbox Code Playgroud)

编译器不够聪明,无法自行解决的原因LengthT是因为它是一个模板参数.它可以是任何东西,因此在模板声明时,编译器无法判断它的值是什么,因此typedef是不明确的.