Inherited vector copy

Hello,
I want to convert a vector from one type to another one.

Like the following :
1
2
vector<NoteTypeA> vec_first;
vector<NoteTypeB> vec_second  = vec_first;


I have the following code:
1
2
3
4
5
6
7
class NodeTypeA {};
class NodeTypeB : public NodeTypeA {
NodeTypeB () : NodeTypeA() {...;}
NodeTypeB (const NodeTypeA & obj) {...;}
NodeTypeB & operator=(const NodeTypeA & obj) { ...return *this;}
};


But It do not want to compile.

The compiler error is : error: no match for ‘operator=’ in ‘vec_second = vec_first’
I get some allocator message.candidates are: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = NodeTypeB, _Alloc = std::allocator<NodeTypeB>]


Do you have any ideas ?

Thanks,
Regards


Last edited on
It doesn't know how assign a NodeTypeA to a NodeTypeB. NodeTypeB has extra fields and it won't know what values to assign them.

You can tell the compiler how to do that assingment by defining the missing assignment operator:
1
2
3
4
5
6
class NodeTypeB
{
public:
    NodeTypeB& operator=(const NodeTypeA &);
    //...
};

and assigning the extra field values that you think are appropriate.
Last edited on
Thanks kbw, but it do not solve my problem.
I think it's due to the fact that vector<T> is typed.
So it could not convert a T1 to a type T2...

I have to try with a master class and use pointer I think...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <vector>
using namespace std;

class NodeTypeA
{
};
class NodeTypeB : public NodeTypeA
{
public:
NodeTypeB () : NodeTypeA() {;}
NodeTypeB (const NodeTypeA & obj) {;}
NodeTypeB & operator=(const NodeTypeA & obj) { return *this;}
};

void main()
{
	vector<NodeTypeA> test;
	vector<NodeTypeB> test2;
	
	test2 = test; //-> generate the error
	return 0;
}
Last edited on
Yes, you're right. You'll have to copy the elements yourself with std::copy. That'll call NodeTypeB& operator=(const NoteTypeA&) for each element.
The only way I have succeed is the following :
1
2
3
4
5
6
7
8
9
10
11

vector<NodeTypeB> vec_second;
vector<NodeTypeA> vec_first;
  vec_first.push_back(NodeTypeA);
  vec_first.push_back(NodeTypeA);
  vec_first.push_back(NodeTypeA);

 vec_second.resize( test.size());

 copy(vec_first.begin(), vec_first.end(), vec_second.begin());


So it copy the sequence into the array vec_second. But it do not do the job as vec_second = vec_first.
You'll need an inserter with the copy.

e.g.
std::copy(vec_first.begin(), vec_first.end(), std::inserter(vec_second, vec_second.begin()));

There's an explanation in Stroustrup's book or you can check online:
stdcxx.apache.org/doc/stdlibug/2-4.html
Thanks.

Do you have a solution that could handle different type via inheritance ?

That could perform something like :
vector<Animals*> = vector< Biped * >;
The issue is the same, finding a relationship between Animal* and Biped* and making up a suitable conversion.
Instead of this:

1
2
vector<NoteTypeA> vec_first;
vector<NoteTypeB> vec_second  = vec_first;


You could use this:

1
2
vector<NoteTypeA> vec_first;
vector<NoteTypeB> vec_second(vec_first.begin(), vec_first.end());
Thanks.

Do you have a solution that could handle different type via inheritance ?

That could perform something like :
vector<Animals*> = vector< Biped * >;


Hmm. Well this doesn't make sense to me. The thread is rather confusing since I am not sure why you would want to make such assignments. You have to pervert the assignment operator to do the assignments in the early examples. However now you are dealing with pointers. If this has something to do with polymorphisism where the vectors contain objects of pointer types where the class inherits from a common base then you need to use a cloning operation. Instead of doing assignment you could use the std::for_each algorithm.

The std::foreach_algorithm is the only one that I know of where the functor can be passed by value and accumulate data. You could use for_each to clone each object from the original and insert it into a new container that is a member of the functor. for_each returns the functor by value which can then be assigned. The call would look something like this. Either that or you have to make your own for loop where you clone each object and insert the clones into the new array. It'd be nice to learn more about your program requirements so that the gurus can help you with whatever you are really having trouble with. I don't agree with the design of having an assignment operator that converts to different data types. That is not what it is for.
So I explain my case of usage.

The fact is that I have created a graph with boost.
And the graph show me relation between the nodes stored in a vector.

I have encapsulated the graph and the vector in a class named genericGraph<T>.

When I used the graphivz file output the boost structure used the ostream operator defined for the node.
So I cannot change the make different version of the ostream operator (a classic, one, a html typed one, ....)

So I have think to change the class of the vector in order to change the ostream operator and so allow a export of new label values.
You could just overload the output operator to achieve what you want.
1
2
3
4
5
6
7
ostream& operator<<(ostream& os, const AnimalsA& aa){
  os << "animal a" << aa.whatever();
}

ostream& operator<<(ostream& os, const AnimalsB& ab){
  os << "animal b" << ab.whatever();
}
Last edited on
This is what I have done, but the problem is the vector copy.

I get the following class :

1
2
3
4
5
6
7
template <class T>
class genericGraph : public boost::adjacency_list<boost::vecS,boost::vecS,DirectedS>
{
...
private:
vector<T> vec_nodes
}


So when I create a genericGraph of AnimalA it cannot be copied to AnimalB.

1
2
3
4
5
6

genericGraph<AnimalA> arbreAnimalA;
...
// The following line do no work :
genericGraph<AnimalB> arbreAnimalB = arbreAnimalA;
// because the vector of AnimalA cannot be converted to AnimalB. 


Thanks for your comments.
Topic archived. No new replies allowed.