views:

115

answers:

2

I want to create a C++ class with the following type:

  1. It can be declared inside of a function.
  2. It can be declared inside of a member function.
  3. It can not be declared as a class member.

The use of this: think "Root" objects for a GC.

Is this possible in C++? In particular, I'm using g++. Willing to switch to clang. Either templates or macro solution fine.

Thanks!

+16  A: 

You could do it with a macro, perhaps:

#define MY_TYPE \
    do { } while(0); \
    RealType

void foo() {
    MY_TYPE myvar;
    myvar.Whatever();
}

This would only compile inside a function (because of the "do ... while" bit - though you'd get a really weird error message). It seems like one of those "evil" uses of macros that you would want to avoid, however...

Dean Harding
Pretty creative. :)
GMan
What happens if you try `const MY_TYPE myvar`?
Will
You could always do `MY_TYPE const myvar` ;)
Dean Harding
This is ##### ingenious.
anon
Very creative !
Matthieu M.
A: 

Even though I gotta love codeka's answer, I cannot but imagine what the problem is with a declaration as a member attribute.

For something like a GC's root I would probably use the Monoid Pattern. All instances of the class are in fact proxies to a Singleton (in essence), ie they all share the same state. This way it doesn't matter how many are instantiated, they all point to the same resource.

If you do so to avoid cyclic references, I am afraid it's not nearly enough.

struct A { boost::shared_ptr<B> mB; };

struct B { boost::shared_ptr<A> mA; };
Matthieu M.
Imagine you're writing a scheme interpreter. Part of the functionality is written in C. Now, GC may happen at any time. However, when the GC runs, we want to make sure that references to scheme bojects on the _C_ stack are treated as root objects.
anon
So you are implementing your GC as a `Mark And Sweep` kind isn't it ? It's customary for this kind to use the stack as root... but I don't like the `freeze the world` it causes, though of course being used to work on servers that have to answer in less than 200ms, I am biased there.
Matthieu M.