J
Juha Nieminen
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.
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?
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 (*)()"?
#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.
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?
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 (*)()"?