Local classes in C++?

R

Rolf Magnus

Kai-Uwe Bux said:
Steven said:
I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code
that I can recall. Is this feature widely supported?

It is in the standard [9.8]. If you find a compiler that does not support
it, the compiler is not compliant.

Is it used?

Sometimes. I think, the feature is of limited use since templates do not
mesh very nicely with local classes.

To be more precise: A local class can't be a template argument, which is
quite unfortunate, since that would be the only reason to define local
classes that I can think of.
 
S

Steven T. Hatton

I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code that
I can recall. Is this feature widely supported? Is it used?

#include <iostream>
struct Bar {
void f() {
struct Local{Local(){std::cout <<"I am local"<<std::endl; }};
Local l;
}
};

int main() {
Bar b;
b.f();
}
 
K

Kai-Uwe Bux

Steven said:
I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code
that I can recall. Is this feature widely supported?

It is in the standard [9.8]. If you find a compiler that does not support
it, the compiler is not compliant.

Is it used?

Sometimes. I think, the feature is of limited use since templates do not
mesh very nicely with local classes.

#include <iostream>
struct Bar {
void f() {
struct Local{Local(){std::cout <<"I am local"<<std::endl; }};
Local l;
}
};

int main() {
Bar b;
b.f();
}


Best

Kai-Uwe Bux
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code that
I can recall. Is this feature widely supported? Is it used?

#include <iostream>
struct Bar {
void f() {
struct Local{Local(){std::cout <<"I am local"<<std::endl; }};
Local l;
}
};

Yes, it's legal. The reason you have not seen it in the book might be
because the usefulness is limited since the class/struct is only
available in the scope in which it was declared.
 
A

Alf P. Steinbach

* Steven T. Hatton:
[rearranged}
#include <iostream>
struct Bar {
void f() {
struct Local{Local(){std::cout <<"I am local"<<std::endl; }};
Local l;
}
};

int main() {
Bar b;
b.f();
}

I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code that
I can recall. Is this feature widely supported?

By all conforming compilers.

Is it used?

Mostly for defining local scope helper functions and small unique
cleanup and adapter classes.

One problem that stands in the way of wider use is that a local class,
as of the current standard, has no linkage.

So you can't do e.g. std::vector<Local>, or use a template function to
obtain the size of Local x[666].
 
F

Frederick Gotham

Steven T. Hatton:
I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code that
I can recall. Is this feature widely supported? Is it used?

#include <iostream>
struct Bar {
void f() {
struct Local{Local(){std::cout <<"I am local"<<std::endl; }};
Local l;
}
};


If you don't mind, I'll make that more readable:

struct Bar {

void f()
{
struct Local {
Local()
{
std::cout << "I am local" << std::endl;
}
};

Local l;
}
};

int main() {
Bar b;
b.f();
}


What's so great about this? I don't understand what you're trying to do. If
you want to embed one function inside another, then simple do:

void Func()
{
struct InnerStruct {
static void OtherFunc()
{
/* Some code */
}
};

InnerStruct::OtherFunc();
}
 
D

David Harmon

On Sat, 02 Dec 2006 11:21:38 +0100 in comp.lang.c++, Rolf Magnus
To be more precise: A local class can't be a template argument, which is
quite unfortunate, since that would be the only reason to define local
classes that I can think of.

What _were_ they thinking?
 
T

tvashtar

or use a functor and do:

int main()
{
struct test
{
void operator() ()
{
//functionality
}
} localfunc;

localfunc();
return 0;
}

I find this handy (almost like a lisp lambda call) for defining little
once off functions on the fly to then pass to for_each etc.
Niall
 
N

Noah Roberts

Rolf said:
Kai-Uwe Bux said:
Steven said:
I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code
that I can recall. Is this feature widely supported?

It is in the standard [9.8]. If you find a compiler that does not support
it, the compiler is not compliant.

Is it used?

Sometimes. I think, the feature is of limited use since templates do not
mesh very nicely with local classes.

To be more precise: A local class can't be a template argument, which is
quite unfortunate, since that would be the only reason to define local
classes that I can think of.

Yeah, I find that rather annoying.
 
J

Jim Langston

David Harmon said:
On Sat, 02 Dec 2006 11:21:38 +0100 in comp.lang.c++, Rolf Magnus


What _were_ they thinking?

Yeah, I've been bitten by that before, wondering why my simple code wouldn't
compile. That should be changed, IMO.

That is, this should compile:

#include <vector>
#include <string>

int main()
{
class MyClass
{
std::string Name;
};

std::vector<MyClass> MyVector;

return 0;
}

but it won't, unless it's on a nonconforming compiler or they change the
specs.
 
S

Steven T. Hatton

Frederick said:
Steven T. Hatton:



If you don't mind, I'll make that more readable:

struct Bar {

void f()
{
struct Local {
Local()
{
std::cout << "I am local" << std::endl;
}
};

Local l;
}
};

If you turn off word wrap you will see what I consider readable in
comparison to the accepted formatting styles.
namespace std {
template<typename T>struct equal_to : binary_function<T, T, bool>{
bool operator()(const T& x, const T& y) const; };
template<typename T>struct not_equal_to : binary_function<T, T, bool>{
bool operator()(const T& x, const T& y) const; };
template<typename T>struct greater : binary_function<T, T, bool>{
bool operator()(const T& x, const T& y) const; };
template<typename T>struct less : binary_function<T, T, bool>{
bool operator()(const T& x, const T& y) const; };
template<typename T>struct greater_equal: binary_function<T, T, bool>{
bool operator()(const T& x, const T& y) const; };
}

sprawling code over multiple lines often accomplishes little more than
hiding symmetries and obscuring higher level structure in a program.
What's so great about this? I don't understand what you're trying to do.
If you want to embed one function inside another, then simple do:
void Func()
{
struct InnerStruct {
static void OtherFunc()
{
/* Some code */
}
};

InnerStruct::OtherFunc();
}

The point was that I didn't think it was possible to define a local class in
C++. IIRC, I tried when I first started with C++ and was not able to make
it work. There are probably numerous modestly useful variants possible for
using local classes.
 
S

Steven T. Hatton

tvashtar said:
or use a functor and do:

int main()
{
struct test
{
void operator() ()
{
//functionality
}
} localfunc;

localfunc();
return 0;
}

I find this handy (almost like a lisp lambda call) for defining little
once off functions on the fly to then pass to for_each etc.
Niall

Thanks. That's slick.

I wonder what the consequences of deriving an inner class from an ABC and
handing ownership off to something outside the call would be. I don't know
if your idiom could be modified to dynamically allocate the object. As it
stands, localfunc will be deallocated when the containing function returns.

It may simply be a path to greater obscurity in code. What I'm thinking
about is something similar to Java's anonymous inner classes. Something
which I found a bit hard to fully comprehend in all of its subtleties.
Nonetheless, it might be handy to have something such as

struct Behavior:public ReferenceCounted {
virtual void activate() = 0;
virtual void suspend () = 0;
};

class Run: public Behavior {
public:
Run (Animal* subject_rptr_):_subject_rptr(subject_rptr_) {}
virtual void activate() { _subject_rptr->animate(); }
virtual void suspend () { _subject_rptr->sleep (); }
private:
ref_ptr<Animal> _subject_rptr;
};

You could then push intrusive pointers to Behaviors onto a
sdt::vector<ref_ptr<Behavior> > which lives outside the function. Since
Run is derived from Behavior, you know how to call its functions even
though you don't have a definition for Run available. I'm just thinking
out loud here. This may be a stupid idea.
 
S

Steven T. Hatton

Rolf said:
Kai-Uwe Bux said:
Steven said:
I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code
that I can recall. Is this feature widely supported?

It is in the standard [9.8]. If you find a compiler that does not support
it, the compiler is not compliant.

Is it used?

Sometimes. I think, the feature is of limited use since templates do not
mesh very nicely with local classes.

To be more precise: A local class can't be a template argument, which is
quite unfortunate, since that would be the only reason to define local
classes that I can think of.

What, exactly, is the restriction? If the local class is derived from a
normal (non-local) base class, would it be possible/useful to instantiate
the template in terms of the base class?
 
S

Steven T. Hatton

Kai-Uwe Bux said:
Steven said:
I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code
that I can recall. Is this feature widely supported?

It is in the standard [9.8]. If you find a compiler that does not support
it, the compiler is not compliant.

Have a look at §14 #1,6 and 7. How many compilers support `export'?
Sometimes. I think, the feature is of limited use since templates do not
mesh very nicely with local classes.

I may simply be deluding myself, but I am beginning to believe deriving
template classes from ABCs is a way to solve a lot of problem with
templates not playing nicely with "regular code". One significant caveat
to that is that templates are frequently used to eliminate the need for
virtual function calls, and still maintain a measure of polymorphism. You
can't have it both ways.
 
K

Kai-Uwe Bux

Steven said:
Kai-Uwe Bux said:
Steven said:
I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code
that I can recall. Is this feature widely supported?

It is in the standard [9.8]. If you find a compiler that does not support
it, the compiler is not compliant.

Have a look at §14 #1,6 and 7. How many compilers support `export'?

Well, what can I say? I certainly have not compiled a statistic about the
support of local classes. If you are not happy with the answer because you
have that nagging feeling that most compilers out there are not compliant,
you may need to write to all compiler vendors possibly of interest you you
and ask about their products.

I may simply be deluding myself, but I am beginning to believe deriving
template classes from ABCs is a way to solve a lot of problem with
templates not playing nicely with "regular code". One significant caveat
to that is that templates are frequently used to eliminate the need for
virtual function calls, and still maintain a measure of polymorphism. You
can't have it both ways.

I do not quite understand. Could you give an example (a) give an example of
how templates do not play nicely with "regular code" [BTW, I find it a
little strange to imply that templated code is "irregular"] and (b) an
example of how deriving a template class from an ABC solves such a problem.


Best

Kai-Uwe Bux
 
R

Rolf Magnus

Steven said:
Rolf said:
Kai-Uwe Bux said:
Steven T. Hatton wrote:

I didn't think this was possible in C++. I don't believe Stroustrup
mentions this anywhere in TC++PL(SE). I've never seen it used in code
that I can recall. Is this feature widely supported?

It is in the standard [9.8]. If you find a compiler that does not
support it, the compiler is not compliant.


Is it used?

Sometimes. I think, the feature is of limited use since templates do not
mesh very nicely with local classes.

To be more precise: A local class can't be a template argument, which is
quite unfortunate, since that would be the only reason to define local
classes that I can think of.

What, exactly, is the restriction?

From the 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."
If the local class is derived from a normal (non-local) base class, would
it be possible/useful to instantiate the template in terms of the base
class?

I'm not sure. You would have to use polymorphism for that. I think the use
would be limited, too.
 
R

Rolf Magnus

tvashtar said:
or use a functor and do:

int main()
{
struct test
{
void operator() ()
{
//functionality
}
} localfunc;

localfunc();
return 0;
}

I find this handy (almost like a lisp lambda call) for defining little
once off functions on the fly to then pass to for_each etc.

That's exactly the problem. You can't do that, because local types can't be
template arguments, so they can't be used with for_each.
 
D

Diego Martins

Rolf said:
That's exactly the problem. You can't do that, because local types can't be
template arguments, so they can't be used with for_each.

and rendering the <algorithm> pretty useless :(

we want lambda now!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top