使用赋值运算符复制std :: vector

时间:2018-09-21 14:18:09

标签: c++ stl

std::vector<MyStruct*> v1;
std::vector<void*> v2;

我有结构指针的stl向量。

我想将std::vector<MyStruct*>复制到std::vector<void*>

如果我使用v2 = v1,我将遇到以下错误:

error C2679: binary '=' : no operator found which takes a right-hand operand of
             type 'std::vector<_Ty>' (or there is no acceptable conversion).

如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

几乎可以肯定,您正在尝试复制包含不同类型元素的向量。即使向量中的 elements 的类型可由编译器转换(例如doubleint),它们的集合也不是。您可以使用std::copy函数对其进行管理,但是:

#include <algorithm>
#include <iterator>
// ...
std::vector v1<int>;
// ...
std::vector v2<double>;
std::copy(v1.begin(), v1.end(), std::back_inserter(v2));

您提到在您的情况下,向量之一包含指针。如果指针类型可由编译器转换,例如,将派生类指针复制到基类指针,则std::copy将如上所述工作。

如果指针不可转换,则必须使用std::transform而不是std::copy,并提供适当的强制转换。例如,将基类复制到派生类指针:

class Y : public class X { ... };
std::vector v3<X*>;
// ...
std::vector v4<Y*>;
std::transform(v3.begin(), v3.end(), std::back_inserter(v4),
               [](X* arg) { return dynamic_cast<Y*>(arg); });

答案 1 :(得分:1)

实际上,OP忽略了必要的细节。

但是,我很敢写一个答案,因为实际上很清楚。

在以下情况下可以分配std::vector的副本

  • 源向量和目标向量具有相同的元素类型
  • 元素类型提供副本分配。

示例:

#include <iostream>
#include <vector>

struct T {
  int value;
};

struct U {
  int value;
  U& operator=(const U&) = delete;
};

int main ()
{
#if 1 // OK:
  { std::vector<T> v1(10), v2;
    v2 = v1;
    std::cout << "After v2 = v1; v2 has size " << v2.size() << '\n';
  }
#else // Wrong: (U has no assignment!)
  { std::vector<U> v1(10), v2;
    v2 = v1;
    std::cout << "After v2 = v1; v2 has size " << v2.size() << '\n';
  }
#endif // 1
  return 0;
}

输出:

After v2 = v1; v2 has size 10

Live demo on coliru

struct T具有(默认)副本分配,但是在struct U中我已明确删除它。

#if 1更改为#if 0,该代码不再编译。


OP提供了缺少的信息后,我的回答将更新:

std::vector::assign()是另一种选择,

  • 源向量的元素类型可以分配给目标向量的元素类型。

在OP的特定情况下,将MyStruct*分配给void*就是如此。

示例:

#include <iostream>
#include <vector>

struct T {
  int value;
};

struct U {
  int value;
  U& operator=(const T &t) { value = t.value; return *this; }
};

int main ()
{
  { std::vector<T> v1(10);
    std::vector<U> v2;
    v2.assign(std::begin(v1), std::end(v1));
    std::cout << "After v2.assign(std::begin(v1), std::end(v1)) v2 has size " << v2.size() << '\n';
  }
#if 1 // OK:
  { T t[] = { { 1 }, { 2 }, { 3 } };
    std::vector<T*> v1{ t + 0, t + 1, t + 2 };
    std::vector<void*> v2;
    v2.assign(std::begin(v1), std::end(v1));
    std::cout << "After v2.assign(std::begin(v1), std::end(v1)) v2 has size " << v2.size() << '\n';
  }
#else // Wrong: (Assignment from void* to T* not permitted!)
  { std::vector<void*> v1(10, nullptr);
    std::vector<T*> v2;
    v2.assign(std::begin(v1), std::end(v1));
    std::cout << "After v2.assign(std::begin(v1), std::end(v1)) v2 has size " << v2.size() << '\n';
  }
#endif // 1
  return 0;
}

输出:

After v2.assign(std::begin(v1), std::end(v1)) v2 has size 10
After v2.assign(std::begin(v1), std::end(v1)) v2 has size 3

Live demo on coliru