views:

262

answers:

3

Hi!

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

+3  A: 

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.

Gamlor
so what would be the correct syntax for the second case which avoids the constructor being called twice? create an object of type bool, but pass an argument of type float to the constructor?
genesys
It has been a while since i've used c++. I guess it would be. `A<bool> a(3.5f)`;
Gamlor
+6  A: 

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.

Suma
is there no version of the constructor that creates a bool version of the object, but takes a float as parameter?
genesys
There is, but to use it you would have to write:A<bool> a(3.5f);If you want to avoid copying by another constructor call, you need to use the direct initialization syntax, not assignment one.
Suma
that's what i was actually looking for :) thank you!
genesys
+6  A: 

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

josefx