Home
Fractals
Tutorials
Books
My blog
My LinkedIn Profile

BOOKS i'm reading

Napoleon Hill Keys to Success: The 17 Principles of Personal Achievement, Napoleon Hill, ISBN: 978-0452272811
The 4-Hour Workweek: Escape 9-5, Live Anywhere, and Join the New Rich (Expanded and Updated), Timothy Ferriss, ISBN: 978-0307465351
The Fountainhead, Ayn Rand, ISBN: 0452273331
Web Hosting Canada

mailto:olivier@olivierlanglois.net

Archives for: August 2007, 19

08/19/07

Permalink 01:04:58 pm, by lano1106, 426 words, 6352 views   English (CA)
Categories: C++

Dependent names and Two-Phase Lookup

Question:

What is wrong in this code from the book 'The C++ Programming Language', section 3.7.2? and why does MSVC accept it and not GCC?

// Range checking vector 
template< class T > class Vec : public std::vector< T >
{ 
public: 
  Vec () : std::vector< T > () { } 
  Vec (int s) : std::vector< T > (s) { } 

  // Range checking by using the at () method,
  // which throws out_of_range 
  T& operator[] (int i) { return at (i); } 
  const T& operator[] (int i) const { return at (i); } 
};

GCC reports this error:

since at() doesn't depend on any template parameters it should be available

Answer:

A compliant compiler will partially validate the template code that does not depend on the template parameters and complete the validation at the template instantiation point. It is that way because code depending on template parameter could have a totally different meaning if between the template declaration and the Point of instantiation (POI) there is a template specialization.

When you call a member function from a template base class, the way it is written is making the name nondependent. To fix the code, 2 options are available. You can either write:

  • this->at(i)
  • std::vector<T>::at(i)

1. is preferred as it will work as expected if the function called is virtual.

If VC++ does not complain, it is because it simply does not support the two phase lookup and compile templates only at instantiation point. GCC is a better compiler in that aspect because it complies with the C++ standard by implementing the Two-Phase lookup. You can easily fool VC++ with the following code:

template <class T> 
class Test 
{ 
public: 
   void Test() { foo(); } 
private: 
   T m_a; 
} 

// Non dependent function declared after
// template declaration
int foo();

int main(int argc, char *argv[]) 
{ 
    Test<int> testObj; 
    testObj.Test(); 
    return 0; 
}

GCC will generate an error when encountering the template complaining that foo() is not declared but VC++ will happily accept this code. Now that this is explained, note that except annoyance when porting code from VC++ to GCC or any other standard compliant compiler, the only consequence for MSVC of not being totally C++ standard compliant by not supporting the Two-Phase lookup is that if there are errors in a template, the compiler will delay their report at its instantiation instead of reporting them as soon as the template is encountered.

If you would like to explore further Dependant base classes, Point of Instantiation (POI) and Two-Phase lookup, I highly recommend to consult the book C++ Templates.

Olivier Langlois's blog

I want you to find in this blog informations about C++ programming that I had a hard time to find in the first place on the web.

August 2007
Sun Mon Tue Wed Thu Fri Sat
 << < Current> >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Search

Custom Search

Misc

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 3

powered by
b2evolution