Re: Completely misleading declaration
Juha Nieminen wrote:
Assume we have a piece of code like this:
#include <map>
struct A { ... };
struct Comp { bool operator()(const A&, const A&) const { ... } };
int main()
{
std::map<A, int, Comp> theMap(Comp());
A a;
theMap[a] = 5;
}
All is well, right? No. gcc gives this error:
error: no match for 'operator[]' in 'theMap[a]'
Inexperienced C++ programmers will be completely confused by this
error message.
Even experienced C++ programmers might be confused with it.
Given the frequency of this error, a compiler can be more
explicit about it. (I seem to recall g++ also outputting
information about the types it was working with.)
Experienced C++ programmers may see what is the problem: What
looks like a map instantiation called 'theMap' actually isn't.
It actually is a function declaration. This even though we are
seemingly creating a (nameless) instance of Comp which we give
to this map as parameter. How can a function be declared with
a parameter which is an instance of a struct instead of being
a parameter type?
Because for historical reasons, C++ declaration syntax is
broken, and there's no easy way to fix it without breaking
existing code.
It seems that we have a doubly-confusing declaration here. In
fact, in this case it doesn't seem to be an instantiation of
Comp at all. Instead, at least according to gcc, it declares
a function pointer type (!)
So, in all its glory, the line:
std::map<A, int, Comp> theMap(Comp());
declares a function named 'theMap' which returns an instance
of std::map<A, int, Comp> and which takes one parameter: A
pointer to a function taking no parameters and which returns
an instance of Comp.
Could this become any more confusing?
A small change in that line completely changes its semantic
meaning:
std::map<A, int, Comp> theMap((Comp()));
Now it does what it looks like it should do: It creates a map
instance called 'theMap' and gives its constructor an instance
of Comp.
Anyways, my actual question is the following:
Is gcc behaving correctly here? Can you really declare a
function pointer type as "Comp()" instead of the more common
"Comp (*)()"?
Yep. You've just run into a case of the most embarassing parse.
I don't think anyone likes the current situation, but to date,
no one has been able to propose an acceptable alternative.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=EF=BF=BDe objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=EF=BF=BDmard, 78210 St.-Cyr-l'=EF=BF=BDcole, France, +33 (0)1 30 2=
3 00 34