stl 向量之间的自动转换
automatic conversion between stl vectors
我想要的是使用赋值运算符将 std::vector<int>
复制到另一个 std::vector<myStruct>
,其中 myStruct
可以分配给 int
。所以我写了这段代码:
#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;
}
它给我错误,因为它找不到 std::vector<myStruct>
和 std::vector<int>
之间的有效转换,尽管 int
可以隐式转换为 myStruct
。另一方面,分配运算符不能在 class 之外声明,因此我推断手动编写运算符不是一种选择。那么遇到这种情况该怎么办呢?
*** 更新:
正如 Blastfurnace
和其他人所说,这可以使用此代码而不是赋值来解决:
vector<myStruct> svec(ivec.begin(), ivec.end());
但想象一下我想编写一个库并希望在库本身中处理它以便用户只需编写 std::vector<myStruct> svec = someFunction()
其中 someFunction
returns std::vector<int>
。没有解决办法吗?
您可以使用采用迭代器范围的构造函数重载:
vector<myStruct> svec(ivec.begin(), ivec.end());
您可以改用vector<myStruct> svec(ivec.begin(), ivec.end());
。
您也可以使用 std::copy(ivec.begin(), ivec.end(), std::back_inserter(svec));
或 svec.assign(ivec.begin(), ivec.end());
,因为如果您分配多次,它可能会更好,因为它可以在清除后重用 vector<myStruct>
的容量。
你最好的选择是有一个转换函数
std::vector< myStruct> convertVector( const std::vector< int> & other)
{
return std::vector< myStruct> ( ivec.begin(), ivec.end() );
}
这将自动使用 return 值优化,因此不会产生两次复制数据的开销(当您迭代 "other" 向量时,您只需复制一次数据)。
为了完整起见:
通过使用自定义数据类型,可以添加自定义类型转换,但我想这通常是个坏主意,无论如何您可能对此不感兴趣:
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>{
//....
};
用法:
int main()
{
IntVector ivec;
ivec.push_back(1);
myStructVector svec = (myStructVector)ivec;
return 0;
}
无论如何我都不鼓励这样做^^
我想要的是使用赋值运算符将 std::vector<int>
复制到另一个 std::vector<myStruct>
,其中 myStruct
可以分配给 int
。所以我写了这段代码:
#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;
}
它给我错误,因为它找不到 std::vector<myStruct>
和 std::vector<int>
之间的有效转换,尽管 int
可以隐式转换为 myStruct
。另一方面,分配运算符不能在 class 之外声明,因此我推断手动编写运算符不是一种选择。那么遇到这种情况该怎么办呢?
*** 更新:
正如 Blastfurnace
和其他人所说,这可以使用此代码而不是赋值来解决:
vector<myStruct> svec(ivec.begin(), ivec.end());
但想象一下我想编写一个库并希望在库本身中处理它以便用户只需编写 std::vector<myStruct> svec = someFunction()
其中 someFunction
returns std::vector<int>
。没有解决办法吗?
您可以使用采用迭代器范围的构造函数重载:
vector<myStruct> svec(ivec.begin(), ivec.end());
您可以改用vector<myStruct> svec(ivec.begin(), ivec.end());
。
您也可以使用 std::copy(ivec.begin(), ivec.end(), std::back_inserter(svec));
或 svec.assign(ivec.begin(), ivec.end());
,因为如果您分配多次,它可能会更好,因为它可以在清除后重用 vector<myStruct>
的容量。
你最好的选择是有一个转换函数
std::vector< myStruct> convertVector( const std::vector< int> & other)
{
return std::vector< myStruct> ( ivec.begin(), ivec.end() );
}
这将自动使用 return 值优化,因此不会产生两次复制数据的开销(当您迭代 "other" 向量时,您只需复制一次数据)。
为了完整起见:
通过使用自定义数据类型,可以添加自定义类型转换,但我想这通常是个坏主意,无论如何您可能对此不感兴趣:
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>{
//....
};
用法:
int main()
{
IntVector ivec;
ivec.push_back(1);
myStructVector svec = (myStructVector)ivec;
return 0;
}
无论如何我都不鼓励这样做^^