Name lookup for names not dependent on template parameter in VC++2008 Express. Is it a bug?
While experimenting a bit with C++ templates I managed to produce this simple code, for which the output is different, than 开发者_Go百科I expected according to my understanding of C++ rules.
void bar(double d)
{
std::cout << "bar(double) function called" << std::endl;
}
template <typename T> void foo(T t)
{
bar(3);
}
void bar(int i)
{
std::cout << "bar(int) function called" << std::endl;
}
int main()
{
foo(3);
return 0;
}
When I compile this code in VC++2008 Express, function bar(int)
gets called. That would be the behaviour, I would expect if bar(3);
in the template body was dependent on the template parameter. But it's not. The rule I found here says "The C++ standard prescribes that all names that are not dependent on template parameters are bound to their present definitions when parsing a template function or class". Am I wrong, that "present definition" of bar
when parsing the template function foo
is the definition of
void bar(double d);
? Why it's not the case if I am wrong. There are no forward declarations of bar
in this compilation unit.
It is indeed a bug in the compiler. The problem was known to exist in VS2005 and before (I use a Blogspot blog as a notebook for cases like this, see 1.3 here). Apparently it is present in VS2008 as well.
You can test it with the following simple code
int bar(double d) { return 0; }
template <typename T> void foo(T t) {
int i = bar(3);
}
void bar(int i);
int main() {
foo(3);
}
This code is well-formed (you can compile it with Comeau Online compiler), but I bet that VS will choke on it because VS implements the two-phase lookup incorrectly in this case.
AndreyT is correct. In fact, your code is virtually identical to an example from the standard (§14.6.3/1):
void g(double);
void h();
template<class T> class Z {
public:
void f() {
g(1); //calls g(double)
h++; //ill-formed: cannot increment function;
// this could be diagnosed either here or
// at the point of instantiation
}
};
void g(int); // not in scope at the point of the template
// definition, not considered for the call g(1)
精彩评论