copy constructor and templated class

Jun 2, 2009 at 11:35am
Hello everyone,

I have a class declaration as follows:

1
2
3
4
template<typename T>
class Matrix
{
};


Now, I want to have a copy constructor. Can I do something like this?

1
2
3
4
template<typename Y>
Matrix(const Matrix<Y> & rhs)
{
}


When I do something like this in my program:

1
2
Matrix<float> mat1;
Matrix<float> mat2 = mat1;


It seems to be calling the default compiler generated copy constructor. I am guessing there are some subtelties to copy constructor and templated classes. Do I need to specify a separate copy constructor when the object templates are of the same type?

Many thanks,

/x
Jun 2, 2009 at 12:39pm
Because Matrix<float> mat2 = mat1; is assignment not copy constructing
Jun 2, 2009 at 12:46pm
Nope.

The above "copy constructor" is not a copy constructor.

The copy constructor is declared as:

 
Matrix( const Matrix<T>& rhs );


which is not the same thing as what you wrote.

If Y == T, then yes, your constructor is a copy constructor. However to the compiler the default copy constructor looks like a specialization that binds tighter than your constructor. Hence the compiler chooses
to call the default copy constructor.

Jun 2, 2009 at 12:48pm
1
2
3
4
5
6
template<typename T>
class Matrix
{
public:
Matrix(const Matrix<T>& rhs);
};

Jun 2, 2009 at 12:58pm
It should go something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

template<typename T>
class Matrix
{
public:
    Matrix();
    Matrix(const Matrix & rhs);
};

template<typename U>
Matrix<U>::Matrix()
{
    std::cout << "Default ctor\n";
}

template<typename V>
Matrix<V>::Matrix(const Matrix & rhs)
{
    std::cout << "Copy ctor\n";
}

int main()
{
    Matrix<float> mat1;
    Matrix<float> mat2 = mat1;
}

Jun 2, 2009 at 3:45pm
Hey,

Thanks everyone for the replies. I now understand that a proper copy constructor has to be defined.

I have just one follow up question. I also want to define a constructor where the RHS can have a implicit convertible type. So that I could convert between the data types (say between float and integers).

So, I have something like following:

1
2
3
4
5
6
template<typename Y>
Matrix<T>(const Matrix<Y> & rhs)
{
    m_rows = rhs.m_rows; // Problem: Cannot access private member m_rows
    m_cols = rhs.m_cols; // same problem.
}


The idea is later I can do:

1
2
3
Matrix<float> mat1;
//
Matrix<int> mat2 = mat1;


In this case, the compiler complains that it cannot access the private member m_rows for the RHS. I am a bit confused as to why this should be. If I access the member through some public function, it is ok. I am wondering why this should cause a problem and if there is something that I can do in the class definition that would make such an implicit conversion possible.

Thanks,

/x
Last edited on Jun 2, 2009 at 3:47pm
Jun 2, 2009 at 6:18pm
They are not the same type.

It is just as if Matrix<Y> were Foo instead. Matrix<> is not allowed to access private/protected elements of Foo unless Matrix is a friend of Foo.

You will need to provide accessors.
Topic archived. No new replies allowed.