我有一对对矢量,我需要将它们线性复制到一个整数矢量。我有以下代码,但是我不确定在C ++中考虑struct padding问题是否安全。
std::vector < std::pair<int, int> > test_vector;
for (int i=0;i<5;i++) {
test_vector.push_back(std::make_pair(i,i*5));
}
std::vector<int> int_vec(test_vector.size() * 2);
std::copy(reinterpret_cast<int*>(&(*test_vector.begin())),reinterpret_cast<int*>(&(*test_vector.end())),int_vec.begin());
现在,我的问题是 - 上述代码是否安全?如果没有,是否有一种优雅的方式来做而不编写循环?
答案 0 :(得分:5)
std::transform
和lambda函数怎么样?
std::vector<int> v;
std::transform(test_vector.begin(), test_vector.end(), std::back_inserter(v),
[&v](const std::pair<int, int> &p)
{ v.push_back( p.first);
return p.second ;});
如果您不能使用C ++ 11,并且可能“讨厌”使用循环进行线性复制
您可以使用像:
这样的仿函数struct X{
X(std::vector<int> &x) :v(x){}
int operator () (const std::pair<int, int> &p)
{
v.push_back(p.first);
return p.second;
}
std::vector<int> &v;
};
std::vector<int> v; //Final vector
std::transform(test_vector.begin(),
test_vector.end(),
std::back_inserter(v),
X(v));
std::vector<int> ::iterator it;
for(it=v.begin() ; it!=v.end() ;++it)
std::cout<<*it<<" ";
答案 1 :(得分:1)
reinterpret_cast
通常是坏消息。难道你不会更好地保留目标向量中的足够空间,然后在对的源向量上调用std::for_each
,然后将函数/ lambda push_back作为第一个和第二个进入目标向量吗?
答案 2 :(得分:1)
关注结构填充问题你是对的,但我认为你并没有真正面对你的代码所做的核心假设:
我可以将
std::pair<int, int>
视为两个整数的数组,.first
是数组中的第一个元素,.second
是第二个元素吗?
从“正确”的角度来看,我会说“不”。您已经确定了填充问题,但也有字段的顺序。实际上无法保证.first
的内存地址低于.second
。
从“实用”的角度来看,我很惊讶你的代码不起作用。 [编辑:Neil指出了一个具有填充问题的具体例子;让我惊讶的颜色。除了“糟糕的形式”,我现在认为代码在实践中被打破了。 ]
对于解决方案,您可以使用for_each
一个自定义操作来推送该对的两个元素(未经测试的代码)
struct action {
action ( vector<int> & target ) : t_(target) {}
void operator () ( const pair &p ) const
{ t_.push_back(p.first); t_.push_back(p.second); }
private:
vector<int> &t_;
}
for_each ( test_vector.begin(), test_vector.end(), action(v));
答案 3 :(得分:1)
这个问题你不需要任何好奇心。一个简单的for循环就行了,特别是如果你不能使用C ++ 11
std::vector < std::pair<int, int> > test_vector;
std::vector<int> int_vec; int_vec.reserve(test_vector.size() * 2);
for (std::vector < std::pair<int, int> >::const_iterator it = test_vector.begin(), end_it = test_vector.end(); it != end_it; ++it)
{
int_vec.push_back(it->first);
int_vec.push_back(it->second);
}