简体   繁体   中英

c++ why is constructor in this example called twice?

I just try to understand the behaviour of the following situation:

template <typename T1>
struct A{
    template <typename T2>
    A(T2 val){
        cout<<"sizeof(T1): "<<sizeof(T1)<<" sizeof(T2): "<<sizeof(T2)<<endl;
    }
    T1 dummyField;
};

so - the class is templated with T1 and the constructor is templated with T2

now - if i write:

A<bool> a = A<bool>(true);

the output is as expected:

sizeof(T1): 1 sizeof(T2): 1

however - if i write:

A<bool> a = A<float>(3.5f);

the output is:

sizeof(T1): 4 sizeof(T2): 4
sizeof(T1): 1 sizeof(T2): 4

why is the constructor called twice with template parameter float?

thanks for satisfying my curiosity

How to avoid copying?

In both cases two constructors are called, however you do not see it in the first case as one of them is the compiler generated one. If you want to avoid copying, you need to use a different syntax, like this:

A<bool> a(true);

A<bool> a(3.5f);

Why (and what) copy constructor is called?

A<bool> a = A<bool>(true);

Here the A (bool val) constructor is used to construct the temporary value, while default compiler generated copy constructor is used to perform the copy of A to A. You are copying the same type, and for same type copy constructor is used. The interesting and not obvious fact here is: Template constructor is never used as a copy constructor, even if it looks like one.

A<bool> a = A<float>(3.5f);

Here A<float>(float val) constructor is used first to construct the temporary value, and then A<bool>( A<float> val) templated constructor is used to perform the copy.

in your first example you make a implicit call to the copy constructor

A<bool>(A<bool> const&)

in your second example this wont work as you have two different types so the compiler has to use your templated constructor to create a new object declaring

 template <typename T2>
A(A<T2>const& val){
    cout<<sizeof(val.dummmyField)<<endl;
}

should make this clear

Because you first create a float-instance of the template class.

This is the A<float>(3.5f) -Part.

Then create the A<bool> by covert the A<float> to a A<bool> . So the constructor is first called for the A<float> -instance. The the copy-constructor of A<bool> is called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM