Re: Crazy Local Class
cpluslearn@gmail.com wrote:
I have a local class inside a function template. I am able to wrap
any type in my local class. Is it legal C++?
Yes, and you actually seem to have made decent use of a potentially
confusing language feature. Nicely done.
What type of class is Local?
Local isn't really a class yet. Each non-specialized instantiation of
the "wrap" function template will be a function, and will include, as
part of its definition, a local class called Local. Each such local
class will be distinct from the others. The name Local will be
meaningful only within the context of its enclosing scope, i.e. within
the definition of the function that is an instantiation of the "wrap"
function template. See also section 9.8 of the current standard,
[class.local].
Is it a class template or regular class?
It's part of the primary definition of a function template; IOW, it's a
blueprint for a class definition, but is neither a template nor a class
in its own right.
Local specifically cannot a template, because templates names have
linkage, whereas Local specifically does not. Local isn't even allowed
to have any member templates.
On the other hand, Local is not a class, but part of a code generation
mechanism that is capable of producing classes as needed. Especially
noteworthy is the fact that different instantiations of the function
template will generate entirely distinct classes based on Local; for
example:
struct foo { virtual ~foo() { } };
template<typename T>
foo* distinct(foo* f =0) {
struct Bar: foo { };
return dynamic_cast<Bar*>(f) ? 0 : new Bar;
}
struct t1;
struct t2;
#include <iostream>
int main() {
foo* const f = distinct<t1>();
std::cout << !!distinct<t1>(f) << '\n'; // 0
std::cout << !!distinct<t2>(f) << '\n'; // 1
}
class Foo
{
public:
virtual ~Foo() {}
virtual void print() = 0;
};
Foo is a class.
template< typename T >
Foo* wrap(const T& t)
{
As you said, wrap is a function template.
class Local : public Foo
{
public:
Local(const T& t):val_(t) { }
void print()
{
cout << "In Local::print()" << val_ << endl;
}
private:
T val_;
};
return new Local(t);
}
Nicely done, except that ownership of the dynamically allocated object
is not clear. You might consider returning a more sophisticated pointer
type, or else making "wrap" a method of a factory object whose
destructor will delete all of the dynamically allocated objects returned
by wrap.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]