equivalent of named arguments for constructors

A

Andrey Vul

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?
 
A

Andrey Vul

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.
 
S

Saeed Amrollahi

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
 
A

Andrey Vul

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?
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top