From: Greg C. <chi...@mi...> - 2002-09-18 03:34:11
|
Oscar Fuentes wrote: > > Greg Chicares <chi...@mi...> writes: > > > Josuttis's example is given below, with comeau and g++3.1 > > results: comeau accepts the code without diagnostics, and > > g++ rejects it. > > Thanks for the example. > > This is the real problem: > > #include <algorithm> > #include <string> > > template <typename T> T foo(T v, T w) { return v+w; } > > char foo(char v) { return v; } > > int main() { > std::string s("hello"); > std::transform( s.begin(), s.end(), s.begin(), foo); > } [snip compiler output: comeau says it's OK, but g++3.2 says no] > *Now*, it seems there is a bug either on g++ or on como > > Bets anyone? ;-) Last time I saw these two compilers disagree, I wrote to Greg Comeau and he said g++ was right. I'm not betting. > > In fact, libcomo uses the same technique: include > > the C <ctype.h> header, then import the names into > > namespace std with using-declarations. > > Comeau and GCC are C/C++ compilers. They save work by re-cycling the C > standard libraries, sacrificing C++ compliance. I don't think this is a library difference, though. From your example I derived this test case: void foo(char) {} template<typename T> void foo(T) {} template<typename Z> void bar(Z) {} int main() {bar(foo);} which comeau accepts and g++3.1 rejects. Viewed this way, I think it's a question about 14.8.2.4/16 . A template-argument can be deduced from a pointer to function or pointer to member function argument if the set of overloaded functions does not contain function templates and at most one of a set of overloaded functions provides a unique match. Note that the Standard does not add "...otherwise, deduction fails." It says "if", but not "only if". So maybe both compilers are right. Here's the example from that section, to which I've added a commented-out line: template<class T> void f(void(*)(T,int)); template<class T> void foo(T,int); // void foo(char,int); // WHAT IF YOU ADD THIS? void g(int,int); void g(char,int); void h(int,int,int); void h(char,int); void m() { f(&g); f(&h); f(&foo); } The standard says f(&h) succeeds, but f(&g) and f(&foo) fail. Both compilers agree. Now uncomment the line marked 'WHAT IF YOU ADD THIS?' Should f(&foo) now succeed? comeau says yes, and g++ says no. I think g++ sees template<class T> void foo(T,int); and says "Hey, there's a function template, so deduction fails" but comeau says "Hey, that function template can't be the deduced type, so disregard it. Then the non-template function is the only candidate, so it's a unique match: deduction succeeds" |