Re: "Simplifying" forward to const - Request for critique
On Aug 31, 10:24 am, Stuart Golodetz <b...@blah.com> wrote:
=D6=F6 Tiib wrote:
On 28 aug, 20:46, Gennaro Prota <gennaro.pr...@yahoo.com> wrote:
I've been having this facility for a long while in my
personal toolset. I thought of it and then never used it.
template< typename C, typename Ret >
Ret &
forward_to_const(
Ret const & ( C::* p )() const,
C const & inst )
{
return const_cast< Ret & >( ( inst.*p )() ) ;
}
It would be used more or less like this:
class C
{
int m ;
public:
...
int const &
f() const
{
return m ;
}
int &
f()
{
#ifdef IMPL_MANUALLY
C const & me( *this ) ;
return const_cast< int & >( me.f() ) ;
#else
return forward_to_const( &C::f, *this ) ;
#endif
}
} ;
I know, of course, that it doesn't handle functions with
parameters, functions returning pointers or even non-member
functions. It isn't meant to be so much general. My
question is rather whether you think it's worth anything or
just adds clutter to the code. The initial motivation was
that I didn't want to think about the
add-const/remove-const manouvre each time I needed such two
"twin" member functions, especially since it doesn't happen
often, so the thinking process is a tad longer. But, having
just encountered a case where I need the twin overloads,
I'm not seeing a clear advantage of using this
forward_to_const stuff.
Seems like a clutter. Forward to non-const from const, it converts
return value automatically:
But requires a const_cast for the call. (Still, it's the
solution I prefer as well.)
That's not such a hot plan, because the actual object on which
you called the const method might be const. Forwarding from
non-const to const is fine, but not the other way round.
Both work equally well. Overloading on const is only really
relevant (supposing no overload abuse) in cases where the
non-const version of the function allows the client code to
modify the object (by returning a non-const reference or pointer
to some interals), but doesn't modify the object itself in any
way. In this case, there's no problem calling the non-const
version from the const.
class C
{
int m;
public:
// ...
int& f()
{
return m;
}
int const& f() const
{
return const_cast< C* >(this)->f();
}
};
Or if return values are identical then remove non-const
member entirely. I miss the reason why to forward to const
member in such a situation.
The return values are identical but the return *types* aren't
- if you remove the non-const member then you can't get an
int& to m any more. You tend to forward to the const member
when:
(a) You need to access something via two different types
depending on whether the object's const or not (e.g. int& and
const int&).
and
(b) There's some non-trivial logic involved in returning the
right value and you don't want to duplicate it.
In the above, (b) isn't satisfied, so you wouldn't bother -
just write return m in each case. But there are some
situations when you would bother.
Yes, and in those cases, I'd generally forward to the non-const
function from the const.
Note that it's also reasonable (often, anyway) for the const
version of the function to return by value, and the non-const by
reference, e.g.:
class Toto
{
int myValue;
public:
int& value()
{
return myValue;
}
int value() const
{
return const_cast<Toto*>(this)->value();
}
};
Obviously, you can't use forward to const here; only forward to
non-const.
--
James Kanze