Patryk Kozak
Patryk Kozak

Reputation: 33

C++ implicit constructor with member's argument list?

Apologies if I am not using C++ nomenclature correctly. I also tried searching StackOverflow and Cppreference but couldn't find information about this case.

Let's take the following piece of code.

struct Foo{
    vector<int> vec; 
    Foo(vector<int> inp) : vec(inp){};
};

struct Bar {
    Foo foo; 
    Bar(Foo inp) : foo(inp) {};   
};

int main()
{
    vector<int> vec = {1,2,3};
    Foo foo(vec);
    Bar bar1(foo);

    Bar bar2(vec);
}

So, I have Bar which has a member Foo. Foo is supposed to be initialised with a vector, while Bar takes Foo as a constructor argument. Nothing unusual here.

Surprisingly, I noticed that I am allowed to do Bar bar2(vec). Looks like there exists an implicitly defined constructor which could look like Bar(vector<int> vec) : foo(vec){} .

This is quite surprising to me. From what I know, c++ only implicitly generates default, move and copy constructs, as well as destructors. In this case, it looks like it generates a constructor which mirrors the member's argument list and passes it to the member's constructor. Is it what happens in reality? Could you please provide some more information about this behaviour?

Upvotes: 1

Views: 147

Answers (1)

songyuanyao
songyuanyao

Reputation: 172884

Foo has a converting constructor taking a vector. In Bar bar2(vec);, vec is implicitly converted to a temporary Foo via the converting constructor, then the temporary Foo is passed to the constructor of Bar as an argument.

You can mark the Foo constructor as explicit to prohibit the implicit conversion:

struct Foo{
    vector<int> vec; 
    explicit Foo(vector<int> inp) : vec(inp){};
};

BTW: Bar::Bar(Foo) is a converting constructor, too.

Upvotes: 4

Related Questions