On Aug 12, 11:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
Alan Woodland wrote:
I was trying to come up with obscure C++ questions in the style of
GoTW and ran across this unexpected difference between G++ and
comeau. Can anyone point me in the direction of the correct result
for this program?
#include <iostream>
namespace A {
class Foo { };
struct f {
public:
f(const Foo& f) { std::cout << "ctor" << std::endl; }
};
}
template <typename T>
void f(const T& t) { std::cout << "Template ref" << std::endl; }
void f(A::Foo& f) { std::cout << "Plain ref" << std::endl; }
int main() {
f(A::Foo());
return 0;
}
G++ doesn't accept it and says:
test.cc: In function 'int main()':
test.cc:5: error: 'struct A::f' is not a function,
test.cc:14: error: conflict with 'void f(A::Foo&)'
test.cc:17: error: in call to 'f'
G++ version was:
g++ (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Whereas Comeau allows it (I only tried it online, so I don't for
certain know what f(A::Foo()); actually resolved to. Comeau version
was:
Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for
ONLINE_EVALUATION_BETA1 Copyright 1988-2007 Comeau Computing. All
rights reserved. MODE:strict errors C++ noC++0x_extensions
AFAICT, G++ is mistaken. It cannot be a construction of a temporary
of type 'f', types are not found using ADL for this syntax. In order
to look 'f' up using ADL, it has to be deemed a function call. By
the time ADL is employed, the syntax 'f(A::Foo())' cannot be
"explicit type conversion (functional notation)". It only can be
"type conversion" if 'f' is already deduced as a type, which it
cannot be since 'A::f' type is not visible.
That may have been the intent---in fact, it probably was, since
the current draft has been changed to state explicitly that ADL
will ignore any names that aren't names of functions. But I'm
not sure that it's that clear in the currently official version
of the standard; it's one of those things which can be
interpreted in different ways. If I interpret the error message
from g++ correctly, it's saying that ADL was applied because
the expression was a function call, and then the results of
function overload resolution meant that it wasn't a function;
the official standard isn't too clear about what to do in this
case, so they treated it as an error.
current wording (or GNU folks' interpretation of it). I don't have
G++ to try this one, but VC++ and Comeau online accept it.