Visual Studio 2008 does not care about base class existence when compiling templates?
It seems that VS 2008 handles class templates with inheritance a bit differently from the other compilers. The following code compiles without any error on VS 2008 (with default options):
template <typename S, typename T>
class someclass : public non_exi开发者_StackOverflow社区stent_class
{
T operator() (S s) const {
return T(s);
}
};
Question is, why? No other compiler has been able to do this (tried GCC 4.5.0, Intel, Online Comeau, VS 2005), because of undefined identifier non_existent_class
. Maybe it is something in the new C++0x standard that justifies this behavior?
This is most likely a consequence of the fact that visual studio does single phase name lookup when it's supposed to do two phase. The non-dependent name "non_existent_class" should fail in the first phase, which happens at the point of definition whether or not the template is ever instantiated.
It's a bug, but it's one that is never, ever going to be fixed until MS fundamentally changes the way their compiler works wrt templates.
http://womble.decadent.org.uk/c++/template-faq.html#two-phase
http://blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html
Visual Studio's compiler was never famous for its standards-compliance. This must be yet another bug, which, in case you'll report it, they'll tell you they have more important stuff to do. Needless to say that once you instantiate the class, the compiler will issue the error.
Yes, there are things which the compiler cannot diagnose before instantiation. This isn't in their count, and the compiler must issue a diagnostic. C++0x doesn't change this rule
When you say that the compiler accepts that code, and other compilers don't, do you mean with that piece of code or also instantiating the template?
Templates are not compiled when the definition is encountered, but rather when they are instantiated. If you are not instantiating the template, it might be the case that the compiler is completely ignoring the whole template definition (in as much as it can, as it needs to be able to interpret enough of the code to know when the template definition finishes).
Then at a later stage, if the template is actually instantiated, and assuming that there is no specialization for the template the compiler will complain. Note that if you provide an specialization for a particular type, that specialization does not need to inherit from the same non-existent class.
In this particular case, I am inclined to think that this is due to the special (as in non-standard) treatment that the Microsoft compiler does of dependent names. In the same way that you don't need to specify typename
in front of a dependent name inside a template (think of a base class, or an instantiation of a different template with a type argument of this template), the compiler might be considering that the base class will be defined before the actual instantiation takes place, and wait for that moment to perform the verification.
精彩评论