Visual C++编译器允许dependent-name作为没有"typename"的类型?

hps*_*use 5 c++ templates dependent-name visual-c++

今天我的一位朋友告诉我,以下代码在他的Visual Studio 2008上编译得很好:

#include <vector>
struct A
{
  static int const const_iterator = 100;
};
int i;
template <typename T>
void PrintAll(const T & obj)
{
  T::const_iterator *i;
}
int main()
{
  std::vector<int> v;
  A a;
  PrintAll(a);
  PrintAll(v);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我通常使用g ++,它总是拒绝传递第二个PrintAll()调用.据我所知,对于这个问题,g ++正在以标准的方式翻译模板.

那么,我的知识是错误的,还是VS2008的扩展?

Mat*_* M. 8

这根本不是一个扩展.

VC++从未正确实现过两个阶段的解释:

  1. 在定义时,解析模板并确定所有非依赖名称
  2. 在实例化时,检查模板是否生成有效代码

VC++从未实现过第一阶段...它不方便,因为它不仅意味着它接受不兼容的代码,而且在某些情况下它会产生完全不同的代码.

void foo(int) { std::cout << "int" << std::endl; }

template <class T> void tfoo() { foo(2.0); }

void foo(double) { std::cout << "double" << std::endl; }

int main(int argc, char* argv[])
{
  tfoo<Dummy>();
}
Run Code Online (Sandbox Code Playgroud)

使用此代码:

  • 兼容的编译器将打印"int",因为它是模板定义时唯一可用的定义,并且分辨率foo不依赖于T.
  • VC++将打印"双",因为它从未打扰过阶段1

差异可能看起来很愚蠢,但是如果你考虑一下大型程序中包含的数量,那么有人会在你的模板代码之后引入一个重载......和BAM:/