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:
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.
This post has 1 feedback awaiting moderation...
Comments are closed for this post.
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.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
<< < | > >> | |||||
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 |