   C++ Templates and Visual Studio 08
  I am starting to work with templates, but I have noticed that I am not getting any compiling errors for obvious faulty code. Here is an example.template<class T>class A {   public: bool Test();};template<class T>bool A<T>::Test() {   asdf;}int main() {   return 0;}When I compile this, Visual Studio 08 does not generate any error messages, but there are 2 errors you can visually see: "asdf;" is not a valid statement and Test() does not return a value. If I remove the template code and make it just a regular class, Visual Studio will generate those 2 errors.Am I doing something wrong?Thanks for any help.   
  Templates aren't actually compiled in until you use them. As you're not using the template anywhere, it won't throw an error.   ;  Ahh. Thank you very much.   ;  Actually that particular snippet should give a compile error (as it does with GCC and Comeau online), as asdf being undefined clearly doesn't depend on how you instantiate the template. It is always an error, regardless of what T actually is.VC++ seems to be implementing templates in its own unique way and doesn't follow the standard always. I don't know if there is a compiler option to make it adhere better.   ;Quote:Original post by visitorActually that particular snippet should give a compile error (as it does with GCC and Comeau online)I'm not sure that it "should" give an error (also, just because one compiler does, doesn't mean all compilers must). The reason is that if you instantiate the template after "asdf" is defined, the code becomes legal (except for the missing return statement). Let's change the code to this:#include <iostream>template<class T>class A {   public: bool Test();};template<class T>bool A<T>::Test() {   asdf;   return false;}int asdf;int main() {   A<int> a;   std::cout << a.Test() << std::endl;   return 0;}We've added a return statement to the A::Test method, and we've defined "asdf" after the template definition. That code compiles in Visual C++ and in comeau (in non-strict C++03 mode), I'm not sure GCC would handle it.If you compile that snippet in strict C++03 mode in Comeau, then the following feature causes it to generate an error (emphasis mine):Quote:http://www.comeaucomputing.com/features.htmlKoenig lookup, aka the argument-dependent lookup rules, are now implemented for templates. This is enabled in strict mode, but disabled in relaxed mode and Microsoft mode, and can also be controlled via --[no_]dep_name. This is significant because much existing code will break. This is so because templates must now be parsed differently. To wit, previously, the named of the function to be called were looked up in the context of the template definition. But with dependent name calls, the function is also look up in the context of the point of instantiation, via argument-dependent lookup. This means more template parsing than previously need to occur, including parsing template definitions at their points of definition. This implies providing names not yet declared, making names visible, and using typename properly.;Quote:Original post by CodekaQuote:Original post by visitorActually that particular snippet should give a compile error (as it does with GCC and Comeau online)I'm not sure that it "should" give an error (also, just because one compiler does, doesn't mean all compilers must). As long as it doesn't spit a diagnostic, it's not valid C++. Visitor is right that non-dependent names are subject to be looked up in a first pass, whereas dependent names are looked up in a second pass (at the point of instantiation).One can easily transform the OP into valid C++ by delaying lookup to the POI:template<class T>class A {   public: bool Test();};template<class T>bool A<T>::Test() {   this->asdf;}int main() {   return 0;}See 9.3: Parsing Templates in the book.   ;  I guess the strict mode is standard-compliant and the non-strict mode is for backward compatibility.The standard (draft) discusses this example like this:8 If a name does not  depend  on  a  template-argument  (as  defined  in  _temp.dep_),  a  declaration  (or  set  of declarations) for that name  shall be in scope at the point where the name appears in the  template  definition;  the  name  is  bound to the declaration (or declarations)  found at that point and this binding is not affected  by  declarations  that are visible at the point of instantiation.  [Example:void f(char);template<class T> void g(T t){   f(1);// f(char)   f(T(1));  // dependent   f(t);// dependent   dd++; // not dependent    // error: declaration for dd not found}void f(int);double dd;void h(){   g(2);   // will cause one call of f(char) followed //  by two calls of f(int)   g('a'); // will cause three calls of f(char)}   --end example]From the looks of it, it could cause some surprises if it wasn't like that (e.g you can't rely on a particular nontemplate function being called in your template, because at the point of instantiation a different function with the same name but better matching signature just happens to be visible; what if the same template is instantiated the same way in two places, except in one that function is not visible?)   ;Quote:Original post by CodekaWe've added a return statement to the A::Test method, and we've defined "asdf" after the template definition. That code compiles in Visual C++ and in comeau (in non-strict C++03 mode), I'm not sure GCC would handle it.Not sure for what the return statement is for, but why should GCC compile it with -std=c++03? It's not valid C++. And I don't really see a point of introducing kludges into a compiler that come into the way of class template specializations, partial specializations and one-definition-rule. Anyways, you can compile your snippets by declaring asdf before using it:#include <iostream>template<typename T>class A {   public: bool Test();};template<typename T>bool A<T>::Test() {   extern int asdf;   asdf;   return false;}int asdf;See Chapter 10: Instantiation in the book.edit: @Codeka, in order to not infringe ODR, how does MSVC handle the case where distinct symbols "asdf" are visible at different (potential) POIs?[Edited by - phresnel on May 7, 2009 4:38:18 AM]