Reputation: 792
What I want is to copy an std::vector<int>
to another std::vector<myStruct>
with assignment operator in which myStruct
can be assigned an int
. So I wrote this piece of code:
#include <vector>
#include <iostream>
using namespace std;
struct myStruct
{
myStruct(int& a) : _val(a) { }
myStruct(int&& a) : _val(a) { }
myStruct& operator=(int& a)
{
_val = a;
return *this;
}
int _val;
};
int main()
{
vector<int> ivec;
ivec.push_back(1);
vector<myStruct> svec = ivec;
return 0;
}
And it gives me error as it cannot find a valid conversion between std::vector<myStruct>
and std::vector<int>
although int
can implicitly be converted to myStruct
. On the other hand, assign operator cannot be declared outside the class so I deduce writing an operator manually is not an option. So what should I do in this situation?
*** UPDATE:
As Blastfurnace
and others said this can be solved using this code instead of assignment:
vector<myStruct> svec(ivec.begin(), ivec.end());
But imagine the situation in which I want to write a library and want to handle this in the library itself so the user can just write std::vector<myStruct> svec = someFunction()
in which someFunction
returns std::vector<int>
. Isn't there any solution for this?
Upvotes: 4
Views: 95
Reputation: 8325
Your best bet is having a conversion function
std::vector< myStruct> convertVector( const std::vector< int> & other)
{
return std::vector< myStruct> ( ivec.begin(), ivec.end() );
}
that would automatically use return value optimization so no overhead for copying the data twice (you just copy data once instead when you iterate the "other" vector).
Just for the sake of completeness:
By using custom datatypes it is possible adding custom type conversion but I guess that's generally a bad Idea and you may not be interested in, anyway:
class IntVector: public std::vector<int>{
public:
//conversion operator (note a VERY BAD IDEA using this, may come in handy in few cases)
operator myStructVector () {
return convertVector(*this);
}
}
class myStructVector: public std::vector< myStruct>{
//....
};
usage:
int main()
{
IntVector ivec;
ivec.push_back(1);
myStructVector svec = (myStructVector)ivec;
return 0;
}
I would discourage going this way anyway ^^
Upvotes: 1
Reputation: 3977
You can use vector<myStruct> svec(ivec.begin(), ivec.end());
instead.
You could also use std::copy(ivec.begin(), ivec.end(), std::back_inserter(svec));
or svec.assign(ivec.begin(), ivec.end());
as it might be better in case you assign multiple times as it can reuse the capacity of the vector<myStruct>
after it was cleared.
Upvotes: 4
Reputation: 18652
You could use the constructor overload that takes an iterator range:
vector<myStruct> svec(ivec.begin(), ivec.end());
Upvotes: 5