C++ 将 pair<int,int> 的向量复制到向量<int>

C++ Copy a vector of pair<int,int> to a vector<int>

本文关键字:int gt lt 向量 复制 C++ pair      更新时间:2023-10-16

我有一个对向量,我需要将它们线性复制到整数向量中。我有以下代码运行良好,但我不确定考虑到C++中的结构填充问题是否安全。

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());

现在,我的问题是 - 上面的代码安全吗?如果没有,有没有一种优雅的方法可以在不编写循环的情况下做到这一点?

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<<" ";

这个问题不需要任何幻想。一个简单的 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);
}

你担心结构填充问题是对的,但我认为你还没有真正面对你的代码正在做出的核心假设:

我可以将std::pair<int, int>视为两个整数的数组,.first是数组中的第一个元素,.second是第二个元素吗?

从"正确性"的角度来看,我会说"不"。您已经确定了填充问题,但还有字段的顺序。实际上无法保证.first的内存地址低于.second

从"实用"的角度来看,我会很惊讶你的代码不起作用。[编辑:尼尔指出了一个存在填充问题的具体例子;所以让我感到惊讶。除了"糟糕的形式"之外,我现在认为代码在实践中被破坏了。]

至于解决方案,您可以将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));

reinterpret_cast通常是个坏消息。在目标向量中保留((足够的空间,然后在成对的源向量上调用std::for_each,然后将函数/lambda push_back到目标向量中吗?