Does the Visual C ++ Compiler allow a dependent name as a type without "typename"?

Today one of my friends told me that the following code compiles well on his 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; } 

I usually use g ++ and always refuse to pass the second call to PrintAll (). As I know, for this problem g ++ makes a standard way to translate a template.

So, my knowledge is wrong, or is it an extension to VS2008?

+5
source share
2 answers

This is not an extension at all.

VC ++ never performed an interpretation of two phases:

  • At the definition point, parse the pattern and identify all non-dependent names
  • At the time of instantiation, ensure that the template generates valid code

VC ++ never implemented the first stage ... this is inconvenient, because it means not only that it accepts incompatible with the code, but also that in some situations it creates completely different code.

 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>(); } 

With this code:

  • compatible compilers will print "int" because this is the only definition available at the template definition point, and the resolution of foo is independent of T
  • VC ++ will print "double" because it never worried about phase 1

This may seem silly compared to the differences, but if you think about the number of inclusions that you have in a large program, there is a risk that someone will present an overload after your template code ... and BAM: /

+8
source

I'm not sure that “extension” is exactly how I would describe VC ++ in this regard, but yes, gcc has a better match in that regard.

+1
source

All Articles