From: Lorenzo Caminiti on
Hello all,

I am new to this groups. I would like to post a C++ programming
question.

Is there a way to access the outer class `this` from a local class but
without using inheritance?

Let me explain with an example:

class x { // outer class
public:
void g() {}

void f() {
this->g(); // (1)

struct y: x { // local class but using inheritance...
y(x* super): x(*super) {} // (2)
void h() {
this->g(); // (3)
}
};
y(this).h();
}
};

*** Is there a way to do this but without inheriting `y` from `x`? ***

At line (3), the local class `y` can access the outer class `x::g()`
simply using `this` because `y` inherits from `x`. However, this
inheritance requires to construct another object `x` when `y` is
constructed as in line (2) adding runtime overhead and requiring `x`
to have an accessible copy constructor.

In my application, I need line (3) to essentially look the same as
like line (1) so you can program code inside `y` members as if it were
inside `x` members. A part from that, the local class `y` could look
as it is needed to solve this problem -- with more member variables,
member functions, etc.

(For example, I tried to redefine `y::operator->()`/`y::operator*()`
to return a pointer/reference to `x` but this does not work because
`this->`/`*this` always retain pointer semantics and do not use the
operators I redefined...)

Thank you very much.

--
Lorenzo

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Goran Pusic on
> Hello all,
>
> I am new to this groups. I would like to post a C++ programming
> question.
>
> Is there a way to access the outer class `this` from a local class but
> without using inheritance?

Bar "code organisation purposes", inner and outer classes have no
connection between them, so, no. Your inner class has to have a
reference to an instance of the outer class (or derive from it).

>
> Let me explain with an example:
>
> class x { // outer class
> public:
> void g() {}
>
> void f() {
> this->g(); // (1)
>
> struct y: x { // local class but using inheritance...
> y(x* super): x(*super) {} // (2)

Using a reference seems a better option here. You never check super
for NULL, and if you ever do y(NULL), you'll crash. In C++, you can
make this design decision spelled out by the syntax.

It is also unusual to construct a derived object by using a conversion
constructor (fancy word for a constructor with one argument) that is
receiving an instance of a base class, but seems justified given the
context (albeit, context is IMO wrong).

> void h() {
> this->g(); // (3)

g is already a public method of x. You could simply do this:

struct y
{
y(x& xx) : _x(x) {}
void h()
{
_x.g();
}
x _x;
}

If g isn't public, and since you are already controlling both classes,
you can make y a friend of x to be able to touch it's private parts.

> At line (3), the local class `y` can access the outer class `x::g()`
> simply using `this` because `y` inherits from `x`. However, this
> inheritance requires to construct another object `x` when `y` is
> constructed as in line (2) adding runtime overhead and requiring `x`
> to have an accessible copy constructor.

Well, you decided to create another object, what did you expect? ;-)

> In my application, I need line (3) to essentially look the same as
> like line (1) so you can program code inside `y` members as if it were
> inside `x` members. A part from that, the local class `y` could look
> as it is needed to solve this problem -- with more member variables,
> member functions, etc.

The thing is, like with many newbie questions, you think that you need
line (3). But in fact, there's probably much more ways to achieve
desired end result, overall (calling g() on an instance of x is just
part of that result). In other words, you should consider changing
your question so that it tells more about what you want to do. The
question you asked is "can I do __this__ so that I can do __that__?".
But __this__ is tangential (and trivial).

> (For example, I tried to redefine `y::operator->()`/`y::operator*()`
> to return a pointer/reference to `x` but this does not work because
> `this->`/`*this` always retain pointer semantics and do not use the
> operators I redefined...)

Yeah, that's a dead end.

HTH,
Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 27 Jul., 06:30, Lorenzo Caminiti <lorcamin...(a)gmail.com> wrote:
> I am new to this groups. I would like to post a C++ programming
> question.

You are welcome to do so!

> Is there a way to access the outer class `this` from a local class
> but without using inheritance?
>
> Let me explain with an example:
>
> class x { // outer class
> public:
> void g() {}
>
> void f() {
> this->g(); // (1)
>
> struct y: x { // local class but using inheritance...
> y(x* super): x(*super) {} // (2)
> void h() {
> this->g(); // (3)
> }
> };
> y(this).h();
> }
> };
>
> *** Is there a way to do this but without inheriting `y` from `x`? ***

Yes, but that requires that y has a constructor accepting
a (reference or pointer to) x and has a member of pointer or
reference type, e.g. like this:

class x { // outer class
public:
void g() {}

void f() {
this->g(); // (1)

struct y { // local class, no inheritance
x* that; // References an object of the outer class
y(x* super): that(super) {} // (2)
void h() {
that->g(); // (3)
}
};
y(this).h();
}
};

Question: Do you have Java background, where it is possible to
define a "non-static" inner class with implied constructor argument
for an object of the outer class?

> At line (3), the local class `y` can access the outer class `x::g()`
> simply using `this` because `y` inherits from `x`. However, this
> inheritance requires to construct another object `x` when `y` is
> constructed as in line (2) adding runtime overhead and requiring `x`
> to have an accessible copy constructor.

Yes, and this idiom is not required.

> In my application, I need line (3) to essentially look the same as
> like line (1) so you can program code inside `y` members as if it were
> inside `x` members. A part from that, the local class `y` could look
> as it is needed to solve this problem -- with more member variables,
> member functions, etc.

But note that there are some restrictions to local classes, among
them it is not feasible to have static data members.

> (For example, I tried to redefine `y::operator->()`/`y::operator*()`
> to return a pointer/reference to `x` but this does not work because
> `this->`/`*this` always retain pointer semantics and do not use the
> operators I redefined...)

This should also work, you can simply define:

x* operator->() const { return that; }

as inline function in y. It is not possible to define any member
functions outside of the local class, though.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Anthony Williams on
Lorenzo Caminiti <lorcaminiti(a)gmail.com> writes:

> Is there a way to access the outer class `this` from a local class but
> without using inheritance?

Pass it in to the local class either as a constructor parameter or a
function parameter:

#include <iostream>
class X
{
private:
void g()
{
std::cout<<"g(), this="<<this<<std::endl;
}
public:
void f()
{
std::cout<<"f(), this="<<this<<std::endl;
struct local
{
X* self;
local(X* self_):
self(self_)
{}

void foo()
{
self->g();
}
};

local y(this);
y.foo();
}
};

int main()
{
X x;
x.f();
}

Anthony
--
Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
just::thread C++0x thread library http://www.stdthread.co.uk
Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Lorenzo Caminiti on
On Jul 27, 10:43 am, Goran Pusic <gor...(a)cse-semaphore.com> wrote:
>
> > In my application, I need line (3) to essentially look the same as
> > like line (1) so you can program code inside `y` members as if it were
> > inside `x` members. A part from that, the local class `y` could look
> > as it is needed to solve this problem -- with more member variables,
> > member functions, etc.
>
> The thing is, like with many newbie questions, you think that you need
> line (3). But in fact, there's probably much more ways to achieve
> desired end result, overall (calling g() on an instance of x is just
> part of that result). In other words, you should consider changing
> your question so that it tells more about what you want to do. The
> question you asked is "can I do __this__ so that I can do __that__?".
> But __this__ is tangential (and trivial).

I want to program code inside `y` members as if it were inside `x`
members. This is my only requirement.

Here's more background information about what I want to do and why.


BACKGROUND

I am programming a macro which evaluates a code expression in constant-
correct context by executing the code from within a local function by
passing the object `this` and other variables as `const`. For example,
the `BLOCK_INVARIANT()` macro can be programmed so that the following:

class c {
public:
c(int x): x_(x) {}

bool eq(int x) const { return x_ == x; };

void f(int x) {
BLOCK_INVARIANT( (const (c*)(this) (int)(x) (this_->eq(x)
== false)) )
}

private:
int x_;
};

Expands to:

class c {
public:
c(int x): x_(x) {}

bool eq(int x) const { return x_ == x; };

void f(int x) {
struct block_invariant {
static void check(c const* const this_, int const& x)
{
if(!( this_->eq(x) == false )) { // Evaluated in
constant-correct context because `this_` and `x` are `const`.
throw int(-1);
}
}
};
block_invariant::check(this, x);
}

private:
int x_;
};

Now the compiler will generate an error if the code expression passed
to `BLOCK_INVARIANT()` -- `this_->eq(x)` in this example -- is not
constant-correct.

However, ideally the code expression passed to `BLOCK_INVARIANT()`
will looks the exactly the same as the code programmed within `f()`.
Therefore, `this_->eq(x)` will ideally be `this->eq(x)`. Is there a
way I can do this without inheriting `block_inv` from `c`? And that is
what I need.


REPLIES

For example, thank you for the following suggestions but they do not
work because:

On Jul 27, 10:43 am, Daniel Kr�gler <daniel.krueg...(a)googlemail.com>
wrote:
> class x { // outer class
> public:
> void g() {}
>
> void f() {
> this->g(); // (1)
>
> struct y { // local class, no inheritance
> x* that; // References an object of the outer class
> y(x* super): that(super) {} // (2)
> void h() {
> that->g(); // (3)
> }
> };
> y(this).h();
> }
> };

Line (3) does not look the same as line (1). In other words, this
solution does not work because I would use `that` inside `y` members
and `this` inside `x` members so line (1) and (3) look different from
each other.

On Jul 27, 10:44 am, Anthony Williams <anthony....(a)gmail.com> wrote:
> #include <iostream>
> class X
> {
> private:
> void g()
> {
> std::cout<<"g(), this="<<this<<std::endl;
> }
> public:
> void f()
> {
> std::cout<<"f(), this="<<this<<std::endl;
> struct local
> {
> X* self;
> local(X* self_):
> self(self_)
> {}
>
> void foo()
> {
> self->g();
> }
> };
>
> local y(this);
> y.foo();
> }
>
> };

Similarly, this does not work because `self->g()` from within the
local function looks different from `this->g()` from within the non-
local function.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]