Boost logo

Boost Users :

Subject: Re: [Boost-users] C++ guru required!
From: Ovanes Markarian (om_boost_at_[hidden])
Date: 2012-02-26 17:18:24


Robert,

I just write the answer which I promised earlier...

On Sun, Feb 19, 2012 at 7:41 PM, Ovanes Markarian <om_boost_at_[hidden]>wrote:

>
>
> On Sun, Feb 19, 2012 at 5:48 PM, Robert Ramey <ramey_at_[hidden]> wrote:
>
>> **
>> Ovanes Markarian wrote:
>> > On Fri, Feb 17, 2012 at 9:40 PM, Robert Ramey <ramey_at_[hidden]> wrote:
>> >
>> > [...]
>> >
>> > Andre Alex... gave a talk at "Going Native" proposing
>> > a "static if" for this case. But I don't see the necessity for
>> > for this since I would assume that the compiler
>> > just optimises away the "dead" code. I've compiled
>> > the above and it seems to do what I want but
>> > still I wonder.
>> >
>> >
>> > Robert, I see Andrey's proposal aimed to replace the enable_if which
>> > is based on SFINAE and greatly simplify the metaprogramming
>> > machinery. The code you present if fine and it might be optimized
>> > away by the compiler, but it might produce compilation errors, since
>> > all runtime branches of if-statement must be compilable without
>> > errors. SFINAE aimes to work around it, like we can enable some
>> > special treatment if the provided code "would compile" without
>> > errors.
>>
>> Basically this example is the first slide in Andrei's talk. The purpose
>> was to introduce a use case for the need for "static if". To my mind
>> it failed in its purpose since a "normal if" already does that. It's even
>> worse - Andrei ruminated on the question as to what should be done
>> with the "dead" branch. i.e. should it be skipped entirely or actually
>> compiled - he left that question open. It seemed to me that for this
>> case, the whole question could be addressed by adding language
>> to the standard that a compiler should elminate code for which
>> it can be determined at compile time will never be run.
>>
> [...]
> Robert, somehow I do not get your proposal. How do you consider an
> if-branch, which is not going to compile, i.e. compilation error. Do you
> propose, to ignore that branch and just state: "OK, if there is a
> compilation error, that must be eliminated without any errors to the
> end-user". I don't think this can work. Therefore there should be a special
> language construct, which states: "if there is a compilation error, than it
> is safe to be ignored during the compilation"
>
> [...]
>
>>
>> > On the other hand using static if we might inspect the exposed type
>> > system of some type T. Let's say we would like to unify some
>> > different types using a traits class. Out traits class should expose
>> > value_type of the inspected type (say we have a boost::shared_ptr and
>> > std::vector as input). boost::shared_ptr contains a typedef of
>> > underlying type which is named element_type and std::vector names the
>> > underlying type value_type. Out traits type should homogenize these
>> > two types and provide a value_type member, which contains the
>> > underlying type of either shared_ptr or std::vector. It can be easily
>> > "calculated/specialized/inspected" with static if construct. How are
>> > you going to solve this problem with the runtime if without using
>> > enable_if , overloads and template specializations?
>>
>> Hmmm - a small code example might make this easier to understand
>>
>>
> [...]
> I am a little bit in hurry today, but will submit the example tomorrow.
>

Sorry it took me a bit longer, but here are my ideas....
Code from Slide 12 of Andrei's presentation at Going Native 2012:

template<class T>
struct container
{
  ...
  static if(debug_mode<T>::value)
  {
    class const_iterator { ... };
    static if(std::is_const<T>::value)
    {
      typedef const_iterator iterator;
    }
    else
    {
      class iterator { ... };
    }
  }
  else
  {
    class const_iterator { ... };
    clas iterator { ... };
  }
};

static if allows to expose the static interface. Now my example was trying
to introduce the following:

Let's assume that shared_ptr<T> only has the element_type type member and
e.g. auto_ptr<T> has the value_type type member.

What we need is to have a machinery to unify these two type templates and
retrieve the type of the pointer from them. This can't be done with runtime
if, but as example shows with static if.

Not sure if C++11 has something similar as MPL's analogon of
BOOST_MPL_HAS_XXX_TRAIT_DEF(name) from:
http://www.boost.org/doc/libs/1_42_0/libs/mpl/doc/refmanual/has-xxx-trait-def.html,
therefore I will use it in my example:

BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type);

template<class PointerWrapper>
struct grab_pointer_type
{
  static if(has_element_type<PointerWrapper>::value)
  {
    typedef typename PointerWrapper::element_type pointer_type;
  }
  else
  {
    typedef typename PointerWrapper::value_type pointer_type;
  }
};

Hope that helps,
Ovanes

>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net