[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Safe and consistent dereferencing and casting [Was: Code revie
From: |
Greg Chicares |
Subject: |
Re: [lmi] Safe and consistent dereferencing and casting [Was: Code review: product editor] |
Date: |
Mon, 16 Apr 2007 16:31:43 +0000 |
User-agent: |
Thunderbird 1.5.0.10 (Windows/20070221) |
On 2007-04-16 08:03Z, Greg Chicares wrote:
> On 2007-04-12 22:43Z, Vadim Zeitlin wrote:
>>
>> there are other similar wrapper functions which we need (notably the
>> function for safely dereferencing a boost::any object)
>
> That's somewhat different from downcasting a wx base-class
> pointer in order to call a derived-class function, so let's
> discuss it separately. I think the technique we're discussing
> here would work in that case without much modification; but
> I have another idea I want to explore for the downcasting case.
My "other idea" was to use static_cast along with a compile-time
assertion that it's valid. However:
[5.2.9/5 == expr.static.cast p 5]
| An lvalue of type "cv1 B" [...] can be cast to type "reference
| to cv2 D", where D is a class derived [...] from B, if [snip
| various requirements...] and B is not a virtual base class
| of D.
The problem is that no one seems to know how to determine at
compile time whether B is a *virtual* base, so we have to keep
dynamic_cast (or risk undefined behavior).
Regardless, is there any objection to adding this assertion:
template<typename T, typename U>
T& safely_dereference_as(U* u)
{
+ // Double parentheses: don't parse comma as a macro parameter separator.
+ BOOST_STATIC_ASSERT
+ ((
+ boost::is_same <U,T>::value
+ || boost::is_base_and_derived<U,T>::value
+ ));
along with the necessary boost headers? HEAD compiles with this
change, with the sole exception that we'd have to remove the
one unit test that it deliberately breaks.
Disadvantage: 'safely_dereference_as' becomes less general.
Advantage: The generality given up isn't useful. Suppose we're
dereferencing a wxControlWithItems* as a wxWindow&; then isn't
our calling code mistakenly designed? I can't see a use case
that we shouldn't forbid; if we discover one later, we can
just remove the assertion.
Note that this change isn't necessary to prevent slicing,
because we're returning a reference. I just think it might
trap a careless oversight.