Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can delegation constructor in C++ be called in the body or just in the initializer list?

Tags:

c++

c++11

as the title says I am curious if delegation constructor can be called in the body or not.

If you are curious about motivation: I have some condition and only workaround I found requires having uselss write on dummy member that occupies space.

#include <iostream>
using namespace std;

struct Delegating {
Delegating (const string& str) {
        cout <<"const string& \n";
}
Delegating(string&& str): dummy_(str.size()>4 ? 0 : (Delegating(str),0))     {
       if (str.size()>4) {
          cout <<"string&& \n";
       }
}
bool dummy_;
};

int main() {
    // your code goes here
    Delegating("abc");
    Delegating("abcde");
    Delegating("abcde");
    Delegating("abcde");
    Delegating("abc");
    cout << "\n--------------------\n";
    Delegating(string("abc"));
    Delegating(string("abcde"));
    Delegating(string("abcde"));
    Delegating(string("abcde"));
    Delegating(string("abcde"));
    Delegating(string("abc"));
    return 0;
}
like image 507
NoSenseEtAl Avatar asked Sep 02 '25 17:09

NoSenseEtAl


1 Answers

Your code does not do what you think it does. By adding a verbose destructor :

~Delegating() {
    std::cout << "~\n";   
}

... the output becomes :

const string& 
~
~
string&& 
~
string&& 
~
string&& 
~
const string& 
~
~
--------------------
(and so on)

Notice there are seven destructor calls, whereas you only instanciated five objects. That's because in the following line :

Delegating(string&& str): dummy_(str.size()>4 ? 0 : (Delegating(str),0)) {

... Delegating(str) is not a delegated constructor call, but an independent temporary object, which is created and destructed during the initialization of dummy_.

The only syntax for delegating constructors is :

Foo(/* params */) : Foo(/* other params */), /* members-init */ {}
//      First one ! ^^^^^^^^^^^^^^^^^^^^^^^

... and it is not possible to conditionally delegate. You can resort to a static function that does the check, and returns a suitably-constructed object (a.k.a the "Named Constructor Pattern").

like image 152
Quentin Avatar answered Sep 04 '25 05:09

Quentin