equivalent of named arguments for constructors

Discussion in 'C++' started by Andrey Vul, Nov 3, 2009.

  1. Andrey Vul

    Andrey Vul Guest

    Given the following:
    class AType;
    class BType;
    class CType;

    AType *AType_init();
    BType *BType_init();
    CType *CType_init();
    AType *a = AType_init();
    BType *b = BType_init();
    CType *c = CType_init();

    class DType {
    public: DType(AType& _a = *a, BType& _b = *b, CType& _c = *c) { }
    };

    Is it possible to call DType::DType() so that only _a and _c are
    explicitly defined and _b uses default? Since C++ is agnostic to
    constructor chaining, DType::DType(AType& _a = *a, CType& _c = *c)
    { DType(_a, *b, _c); } won't have the intended effect. Or will it?

    Having commas causes syntax errors, but is there a way to call
    constructors so that arguments L, M, and N (by argument index) are
    explicitly defined without kludging up constructors as done in the
    previous paragraph?
    Andrey Vul, Nov 3, 2009
    #1
    1. Advertising

  2. Andrey Vul

    Andrey Vul Guest

    On Nov 3, 12:11 am, Andrey Vul <> wrote:

    Edit:
    modify
    > DType::DType(AType& _a = *a, CType& _c = *c)

    to
    DType::DType(AType& _a, CType& _c)

    The default arguments in the reduced constructor make constructor
    choice ambiguous and thus illegal.
    Andrey Vul, Nov 3, 2009
    #2
    1. Advertising

  3. On Nov 3, 8:11 am, Andrey Vul <> wrote:
    > Given the following:
    > class AType;
    > class BType;
    > class CType;
    >
    > AType *AType_init();
    > BType *BType_init();
    > CType *CType_init();
    > AType *a = AType_init();
    > BType *b = BType_init();
    > CType *c = CType_init();
    >
    > class DType {
    > public: DType(AType& _a = *a, BType& _b = *b, CType& _c = *c) { }
    >
    > };
    >
    > Is it possible to call DType::DType() so that only _a and _c are
    > explicitly defined and _b uses default? Since C++ is agnostic to
    > constructor chaining, DType::DType(AType& _a = *a, CType& _c = *c)
    > { DType(_a, *b, _c); }  won't have the intended effect. Or will it?
    >
    > Having commas causes syntax errors, but is there a way to call
    > constructors so that arguments L, M, and N (by argument index) are
    > explicitly defined without kludging up constructors as done in the
    > previous paragraph?



    Hi Andrey

    There are several related items here:
    1. Default arguments may be provided for trailing arguments only. I
    can't declare/define
    a function like this:
    DType::DType(AType& _a = *a, BType& _b, CType& _c = *c) { }
    2. Because C++ uses arguments based on position rather than name, a
    possible workaround
    for your problem is to switch second and third parameter:
    DType::DType(AType& _a = *a, CType& _c = *c, BType& _b = *b) { }
    // ...
    DType D(*AType_init(), *CType_init());
    3. Again, because C++ uses arguments based on position rather than
    name, A solution
    is suggested by experts called "Named Parameters Idiom". It is very
    useful for a class
    with constructors and mostly default values for data members:
    class DType {
    AType a;
    BType b;
    CType c;
    public:
    DType() {}
    DType& A() { a = *AType_init(); return *this; }
    DType& B(BType& b_) { b = b_; return *this; }
    DType& C() { c = *CType_init(); return *this; }
    };

    // use DType
    DType d().A().C();
    // use BType explicit
    // ...

    I recommend see the D&E by Bjarne Stroustrup under "Keyword Arguments"
    and the following
    link:
    http://parashift.com/c -faq-lite/ctors.html#faq-10.18
    4. FYI, in C++0x (next revision of C++), we will have delegating
    constructor, so we can call
    one constructor in another one.

    I hope it helps,
    -- Saeed Amrollahi
    Saeed Amrollahi, Nov 3, 2009
    #3
  4. Andrey Vul

    Andrey Vul Guest

    On Nov 3, 2:53 am, Saeed Amrollahi <> wrote:
    > On Nov 3, 8:11 am, Andrey Vul <> wrote:
    >
    >
    >
    > > Given the following:
    > > class AType;
    > > class BType;
    > > class CType;

    >
    > > AType *AType_init();
    > > BType *BType_init();
    > > CType *CType_init();
    > > AType *a = AType_init();
    > > BType *b = BType_init();
    > > CType *c = CType_init();

    >
    > > class DType {
    > > public: DType(AType& _a = *a, BType& _b = *b, CType& _c = *c) { }

    >
    > > };

    >
    > > Is it possible to call DType::DType() so that only _a and _c are
    > > explicitly defined and _b uses default? Since C++ is agnostic to
    > > constructor chaining, DType::DType(AType& _a = *a, CType& _c = *c)
    > > { DType(_a, *b, _c); }  won't have the intended effect. Or will it?

    >
    > > Having commas causes syntax errors, but is there a way to call
    > > constructors so that arguments L, M, and N (by argument index) are
    > > explicitly defined without kludging up constructors as done in the
    > > previous paragraph?

    >
    > Hi Andrey
    >
    > There are several related items here:
    > 1. Default arguments may be provided for trailing arguments only. I
    > can't declare/define
    > a function like this:
    >    DType::DType(AType& _a = *a, BType& _b, CType& _c = *c) { }
    > 2. Because C++ uses arguments based on position rather than name, a
    > possible workaround
    > for your problem is to switch second and third parameter:
    >    DType::DType(AType& _a = *a, CType& _c = *c, BType& _b = *b) { }
    >    // ...
    >    DType D(*AType_init(), *CType_init());
    > 3. Again, because C++ uses arguments based on position rather than
    > name, A solution
    > is suggested by experts called "Named Parameters Idiom". It is very
    > useful for a class
    > with constructors and mostly default values for data members:
    >   class DType {
    >     AType a;
    >     BType b;
    >     CType c;
    >    public:
    >      DType() {}
    >      DType& A() { a = *AType_init(); return *this; }
    >      DType& B(BType& b_) { b = b_; return *this; }
    >      DType& C() { c = *CType_init(); return *this; }
    >   };
    >
    >   // use DType
    >   DType d().A().C();
    >   // use BType explicit
    >   // ...


    Would it be correct to refer to this idiom as a this-chain constructor?
    Andrey Vul, Nov 4, 2009
    #4
  5. Andrey Vul

    Andrey Vul Guest

    On Nov 3, 8:55 pm, Andrey Vul <> wrote:

    > this-chain constructor?

    should be
    this-chain construction

    sorry for the typo
    Andrey Vul, Nov 4, 2009
    #5
  6. On Nov 4, 5:01 am, Andrey Vul <> wrote:
    > On Nov 3, 8:55 pm, Andrey Vul <> wrote:
    >
    > > this-chain constructor?

    >
    > should be
    > this-chain construction
    >
    > sorry for the typo


    Hi

    The better/offical name is "Method Chaining". Please see the following
    link:
    http://www.parashift.com/c -faq-lite/references.html#[8.4]
    In "Named Parameter Idiom", we usually use method chaining technique.

    Regards,
    -- Saeed Amrollahi
    Saeed Amrollahi, Nov 4, 2009
    #6
    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. Dave Rudolf
    Replies:
    12
    Views:
    8,245
    Martijn Lievaart
    Feb 6, 2004
  2. Jeremy Smith
    Replies:
    2
    Views:
    572
    Jeremy Smith
    Aug 3, 2006
  3. Jess
    Replies:
    5
    Views:
    582
    Ron Natalie
    Jun 7, 2007
  4. Peng Yu
    Replies:
    5
    Views:
    381
    Juha Nieminen
    Sep 19, 2008
  5. Roger Pack
    Replies:
    2
    Views:
    101
    Roger Pack
    Jan 4, 2010
Loading...

Share This Page