Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Nonconst method calls enumerator with const_cast

31 views
Skip to first unread message

Frederick Gotham

unread,
Apr 10, 2019, 4:47:04 AM4/10/19
to
Can I do any better than reinterpret_cast in the following code? The GNU compiler won't accept const_cast in its place.


void MyClass::Enumerate( void (*const pFunc)(MyPOD const*) ) const
{
for (size_t i = 0; i != capacity; ++i)
{
if ( p_data[i].e[0] != '\0' )
pFunc(p_data + i);
}
}

void MyClass::Enumerate( void (*const pFunc)(MyPOD*) ) /* Not const because pointer is not to const */
{
const_cast<MyClass const *>(this)->Enumerate( reinterpret_cast<void (*)(MyPOD const *)>(pFunc) );
}

Hope all is well here on the board.... I haven't posted in 10 years or so.

Frederick

Öö Tiib

unread,
Apr 10, 2019, 6:04:38 AM4/10/19
to
On Wednesday, 10 April 2019 11:47:04 UTC+3, Frederick Gotham wrote:
> Can I do any better than reinterpret_cast in the following code? The GNU compiler won't accept const_cast in its place.

It is reinterpret casting between different function types, then calling
those. I do not think that any implementation has defined what happens
when we do that. So in short it is probably illegal, all bets off thing to
do.

> void MyClass::Enumerate( void (*const pFunc)(MyPOD const*) ) const
> {
> for (size_t i = 0; i != capacity; ++i)
> {
> if ( p_data[i].e[0] != '\0' )
> pFunc(p_data + i);
> }
> }
>
> void MyClass::Enumerate( void (*const pFunc)(MyPOD*) ) /* Not const because pointer is not to const */
> {
> const_cast<MyClass const *>(this)->Enumerate( reinterpret_cast<void (*)(MyPOD const *)>(pFunc) );
> }

From your post it is unclear why you can't just erase that non-const
MyClass::Enumerate and pass function pointer of correct type to other
one always.

Alf P. Steinbach

unread,
Apr 10, 2019, 6:10:21 AM4/10/19
to
E.g.,


--------------------------------------------------------------------------------------------------
using Size = ptrdiff_t;
using Index = ptrdiff_t;

template< class T > using P_ = T*;
template< class T > using Type_ = T;

namespace my
{
using std::vector;

struct Pod { char e[80]; };

class Class
{
vector<Pod> m_data;

template< class Self, class Func >
friend void enumerate_on( Self& self, const Func f )
{
for( auto& item: self.m_data )
{
if( !!item.e[0] ) { f( &item ); }
}
}

public:
// void enumerate( void (*const pFunc)(MyPOD const*) ) const
void enumerate( const Type_<void( const Pod* )> f ) const
{
enumerate_on( *this, f );
}

// void MyClass::Enumerate( void (*const pFunc)(MyPOD*) ) /*
Not const because pointer is not to const */
void enumerate( const Type_<void( Pod* )> f )
{
enumerate_on( *this, f );
}
};
};
--------------------------------------------------------------------------------------------------


With that basic technique understood, consider letting the function type
be just a template parameter also in the public interface.

Unless these functions are meant to be called from C.


Cheers & hth.,

- Alf

Melzzzzz

unread,
Apr 10, 2019, 12:40:15 PM4/10/19
to
Const and non const call is resolved by first hidden argument, that is, 'this'.
So if you call Enumerate with non cost object non const version is
called otherwise const...

--
press any key to continue or any other to quit...
0 new messages