Can I define a constructor from another one?

Viewed 67

Here's a dummy example to illustrate:

class C
{
    // complex class with many fields and methods 
    // including very expensive:
    int computeA();
    int computeB();
}

struct S
{
    S(int a, int b); // initializes as {a, b, a*b};
    // how to define below constructor?
    S(const C& c); // Should be equivalent to calling S(c.computeA(), c.computeB())

    int a;
    int b;
    int ab;
}

I'm probably missing something simple but all my attempts are syntactically incorrect. I can obviously circumvent the problem by using a helper function rather than a constructor, but is there a proper way to define such constructor directly?

And of course I don't want to do this:

S(const C& c); // initialize as {c.computeA(), c.computeB(), c.computeA()*c.computeB()};

because of repeating unnecessarily expensive computations.

2 Answers

This code does what you want

S(const C& c) : S(c.computeA(), c.computeB()) {}

It's called a delegating constructor and is available from C++11.

You can delegate the constructor:

struct C
{
    int computeA() const;
    int computeB() const;
};

struct S
{
    S(int a, int b) : a(a),b(b),ab(a*b) {}
    S(const C& c) : S(c.computeA(),c.computeB()) {}

    int a;
    int b;
    int ab;
};

There are so many errors in the code you posted that I do not want to list them here, as they aren't really related to the actual question. In at least one case I had to guess what you mean (is const C& right or are the methods correctly non-const, I chose the former).


Fwiw, before delegating constructors were available (C++11) a possible workaround was a static method or free function:

 S make_S(const C& c) {
      return S(c.computeA(),computeB());
 }

With the downside that this is not an implicit conversion. Which can actually be considered as a plus and I would suggest to also make the converting constructor above explicit.

Related