Lambda's in member initializer lists - style question

Discussion in 'C++' started by Werner, Oct 19, 2012.

  1. Werner

    Werner Guest

    Hi All,

    I've found an interesting use for lambdas in member initializer
    lists, and I've wondered if this would be frowned upon from a style
    perspective:

    Plot::plot()
    : curve_( []( Plot& plot )
    {
    std::unique_ptr<Curve> curve( new Curve );
    curve->setZ_Order( 20 );
    curve->associate( plot );
    return curve;
    }( *this ),
    etc...
    {
    }

    as opposed to:

    Plot::plot()
    : curve_( new Curve )
    {
    //Initialization seperated from creation...
    initialiseCurve();
    }

    I like the idea of using the lambda (or a creation function)
    because if initialization fails, creation should too, and then
    it would not benefit to create the rest of the object.

    OTOH, inter-dependencies may exist between objects:

    Widget::Widget()
    : plot_(...),
    curve_( []( Plot& plot ) //Curve depends on plot...
    {
    std::unique_ptr<Curve> curve( new Curve );
    curve->setZ_Order( 20 );
    curve->associate( plot );
    return curve;
    }( *plot_ ),
    etc...
    {
    }

    This creates the risk that plot does not exist, especially if
    member declaration order is different to the order in the
    member initializer list. On the other hand most compilers
    do warn about this kind of thing.

    Any thoughts on this style issue?

    Kind Regards,

    Werner
    Werner, Oct 19, 2012
    #1
    1. Advertising

  2. Werner <> writes:

    > I've found an interesting use for lambdas in member initializer
    > lists, and I've wondered if this would be frowned upon from a style
    > perspective:
    >
    > Plot::plot()
    > : curve_( []( Plot& plot )
    > {
    > std::unique_ptr<Curve> curve( new Curve );
    > curve->setZ_Order( 20 );
    > curve->associate( plot );
    > return curve;
    > }( *this ),
    > etc...
    > {
    > }
    >
    > as opposed to:
    >
    > Plot::plot()
    > : curve_( new Curve )
    > {
    > //Initialization seperated from creation...
    > initialiseCurve();
    > }


    Sorry, but why isn't that:

    Plot::plot() : curve_(20,this), etc...
    {
    }

    I mean, your lambda doesn't do anything but setting up a Curve object,
    so why is this not part of Curve's construction?


    > OTOH, inter-dependencies may exist between objects:
    >
    > Widget::Widget()
    > : plot_(...),
    > curve_( []( Plot& plot ) //Curve depends on plot...
    > {
    > std::unique_ptr<Curve> curve( new Curve );
    > curve->setZ_Order( 20 );
    > curve->associate( plot );
    > return curve;
    > }( *plot_ ),
    > etc...
    > {
    > }
    >
    > This creates the risk that plot does not exist, especially if
    > member declaration order is different to the order in the
    > member initializer list.


    This can't be, as far as I know. Members have to be initialized in the
    order with which they are declared.

    -- Alain.
    Alain Ketterlin, Oct 19, 2012
    #2
    1. Advertising

  3. Werner

    Werner Guest

    On Friday, October 19, 2012 11:41:57 AM UTC+2, Alain Ketterlin wrote:

    > Sorry, but why isn't that:
    >
    >
    >
    > Plot::plot() : curve_(20,this), etc...
    >
    > {
    >
    > }



    > I mean, your lambda doesn't do anything but setting up a Curve object,
    > so why is this not part of Curve's construction?


    - You don't necessarily have control over curve's
    construction.
    - In the above event, you could create a class in an anon
    namespace that is just responsible for the construction itself:
    namespace {
    class MyCurve : OrignalCurve
    {
    MyCurve( appropriate members for proper construction... )
    };
    }

    but IMhO if only required once, the lambda is less work...

    > This can't be, as far as I know. Members have to be initialized in the
    > order with which they are declared.


    Yes, they have to be:

    class X
    {
    ....
    Curve* curve_;
    Plot* plot_;
    ....
    };

    X::X()
    : plot_( new Plot ),
    curve( new Curve( *plot_ ) )
    { }

    The compiler is not forced to give a diagnostic
    in this case, and plot has not been initialized yet,
    because members [are] initialized in the order they
    are declared, and not in the order specified in
    the member initializer list.

    Regards,

    Werner
    Werner, Oct 19, 2012
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pmb
    Replies:
    2
    Views:
    373
  2. Roman Suzi
    Replies:
    13
    Views:
    588
    Bengt Richter
    Jan 7, 2005
  3. =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==

    List of lists of lists of lists...

    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==, May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    384
    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==
    May 15, 2006
  4. Steve Dogers

    lambda vs non-lambda proc

    Steve Dogers, Mar 30, 2009, in forum: Ruby
    Replies:
    1
    Views:
    156
    Sean O'Halpin
    Mar 30, 2009
  5. Haochen Xie
    Replies:
    4
    Views:
    232
    Haochen Xie
    Mar 17, 2013
Loading...

Share This Page