We all know you can simulate closures in C++98 by defining local structs/classes inside a function. But is there some reason that locally defined structs can't be used to instantiate templates outside of the local scope?
For example, it would be really useful to be able to do things like this:
void work(std::vector<Foo>& foo_array)
{
struct compareFoo
{
bool operator()(const Foo& f1, const Foo& f2) const
{
return f1.bar < f2.bar;
}
};
std::sort(foo_array.begin(), foo_array.end(), compareFoo());
}
This would be especially useful if you know you're not going to need to use compareFoo anywhere else in your code. But, alas, this doesn't compile. Is there some reason that the compiler can't instantiate the std::sort template function using a locally defined struct?
There's no better reason than "it's not allowed by the standard".
I believe C++0x is going to lift this restriction, and allow you to use local classes as template parameters freely. But for now, it's not allowed.
See GOTW #58 - you can't use locally defined classes as arguments to templated types, e.g. vector wouldn't be allowed.
From the C++ standard (14.3.1/2):
A local type, a type with no linkage, an unnamed
type or a type compounded from any of these types
shall not be used as a template-argument for a
template type-parameter. [Example:
template <class T>
class X { /* ... */ };
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as
// template-argument
X<S*> x4; // error: pointer to local type
// used as template-argument
}
--end example]
Although I don't read this as meaning template functions like std::sort can't use a local class as an argument, apparently gcc thinks otherwise.
The local classes have no linkage (no global name), which seems like something that helps overburned compiler writers and hurts actual programmers. To actually allow a local class S to be used in vector<S>
or some function<..,S>
, I guess the generated thing would need a unique global name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With