Deep const-ness in array of pointers?

S

spacewrench

I'd like to give an array of pointers to a class instance, and let the
instance return references (either const or mutable) to the array
elements. However, when I return a const reference to one of the
pointers, I can still modify the pointed-to object through the pointer
(I just can't change to pointer to point to a different object).
Instead, I'd like to have the const-ness "trickle down," so that if I
return a const pointer, it's actually a const * const. (This is a
poor English description of the following code.) I'm using g++-4.3.2,
and it warns about returning a reference to a temporary in whynot().
I don't understand why a temporary must be created in this situation.
Is it a g++ anomaly, or is there a sneaky problem with what I'm trying
to do?

class Foo {
public:
void inspect( void ) const { }
void mutate( void ) { }
} ;

class Bar {
public:
Bar( Foo *a[] ) : arrayOfFoo( a ) { }

Foo * & elt ( unsigned n ) { return arrayOfFoo
[n]; }
Foo * const & elt ( unsigned n ) const { return arrayOfFoo
[n]; }
const Foo * const & whynot( unsigned n ) const { return arrayOfFoo
[n]; }

private:
Foo * * const arrayOfFoo;
} ;


int
main( int, char ** )
{
Foo *foo[10];
Bar bar( foo );
const Bar &cbar = bar;

bar.elt( 0 )->inspect( );
bar.elt( 1 )->mutate( );

cbar.elt( 2 )->inspect( );
cbar.elt( 3 )->mutate( ); // <--- Don't want to allow this

cbar.whynot( 4 )->inspect( );
cbar.whynot( 5 )->mutate( ); // <--- this gives error (yay!)

return 0;
}


Thanks,
dave m.
 
T

Triple-DES

[snip]
class Foo {
  public:
    void     inspect( void ) const { }
    void     mutate( void )        { }

} ;

class Bar {
  public:
    Bar( Foo *a[] ) : arrayOfFoo( a ) { }

          Foo *       & elt   ( unsigned n )       { return arrayOfFoo
[n]; }
          const Foo * elt   ( unsigned n ) const { return arrayOfFoo
[n]; }
    const Foo * const & whynot( unsigned n ) const { return arrayOfFoo
[n]; }

  private:
    Foo * * const arrayOfFoo;

} ;

int
main( int, char ** )
{
    Foo       *foo[10];
    Bar        bar( foo );
    const Bar &cbar = bar;

    bar.elt( 0 )->inspect( );
    bar.elt( 1 )->mutate( );

    cbar.elt( 2 )->inspect( );
    cbar.elt( 3 )->mutate( );   // <--- Don't want to allow this [snip]
}

Hi, for the elt function, why not simply specify the return type as
"Foo *" and "const Foo *"?
 
S

spacewrench

Hi, for the elt function, why not simply specify the return type as
"Foo *" and "const Foo *"?

Because I need to be able to alter the pointer array through the
holding class if I have a non-const holding-class object. For
example, I might have:

Foo a;
Foo b;

bar.elt( 0 ) = &a;
cbar.elt( 0 )->inspect( ); // inspect a
bar.elt( 0 ) = &b;
cbar.elt( 0 )->inspect( ); // inspect b

but:

cbar.elt( 0 ) = 0; // Error!
 
S

spacewrench

Here's a link to the thread  from a few weeks ago (news and web links):

Thanks very much! That's a weird workaround -- I wouldn't have
guessed to do it that way, but it makes g++ happy...

Regards,
d.
 

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
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top