【问题标题】:Overloading operator= for struct members of class std::vector<>为类 std::vector<> 的结构成员重载 operator=
【发布时间】:2019-06-09 14:00:19
【问题描述】:

假设我有以下结构:

struct Parameter {
  double value;
  double error;
};

所以我通常使用该结构的向量(即std::vector&lt;Parameter&gt;),偶尔我想设置一个 values 的向量(但不是 errors) 为方便起见,使用带有标准 std::vector 的 operator= 在该参数向量中。

std::vector<Parameter> vector_of_parameters;
std::vector<double> vector_of values;
....
vector_of_parameters = vector_of_values;

为此,我正在尝试为此结构重载operator=,如下所示:

std::vector<Parameter> operator=(const std::vector<double>& v) {
  this->clear();
  for (const auto& i:v) {
    Parameter p;
    p.value = i;
    this->push_back(p);
  }
  return *this;
}

但这会返回一个错误,指出 std::vector operator=(const std::vector& v) 必须是非静态成员。所以如果我理解正确的话,我必须把它定义为运算符的成员函数:

std::vector<Parameter>::operator=(const std::vector<double>& v) {
  this->clear();
  for (const auto& i:v) {
    Parameter p;
    p.value = i;
    this->push_back(p);
  }
  return *this;
}

现在的错误是 syntaxis with template,但我并没有真正看到或理解它,也不知道我还能做什么。

【问题讨论】:

  • 您不能定义未在类中声明的类成员函数(如operator=)(包含文件vector)。所以你需要写一个像void assign(std::vector&lt;Parameter&gt; &amp;out, const std::vector&lt;double&gt; &amp;in)这样的免费函数,或者更好地使用std::transform
  • 阅读this page 了解有关复制分配的更多信息。您是正确的,复制分配必须是成员函数。但是您还尝试使用您的自定义类型 Parameterstd::vector 进行模板专业化,请查看 here 了解更多信息。
  • 不确定,但您似乎认为结构与类有所不同。它们不是。C++ 只有可以使用structclass 两个关键字中的任何一个声明的类,区别仅在于成员和基类的默认访问权限。
  • 您不能为不属于您的类(例如 std::vector)重载赋值运算符。语言不允许这样做,但这并不重要;主要问题是它只是一个极其危险的想法(当然这正是语言不允许它的原因)。

标签: c++ vector struct


【解决方案1】:

您不能重载std::vector 的赋值运算符。 operator = 必须是成员函数,您不能将成员函数添加到 std::vector

您可以做一个类似create_parameters 的便捷函数,它接受std::vector&lt;double&gt; 并返回std::vector&lt;Parameter&gt;。看起来像

std::vector<Parameter> create_parameters(std::vector<double> const& params)
{
    std::vector<Parameter> ret(params.size());
    std::transform(params.begin(), params.end(), ret.begin(),
                   [](auto value) { return Parameter{value, 0}; });
    return ret;
}

然后

vector_of_parameters = vector_of_values;

会变成

vector_of_parameters = create_parameters(vector_of_values);

【讨论】:

  • 虽然这看起来很有希望,但它会返回一个错误“在')'之前的预期主表达式”。我不太了解 std::transform 中的语法,也无法修复它。
  • @EuGENE 哎呀。我错过了关闭},现在已修复。这是一个lambda expression
  • 现在可以了,谢谢!!顺便说一句,非常有启发性的答案;)
【解决方案2】:

我认为从std::vector&lt;double&gt; 创建std::vector&lt;Parameter&gt; 的另一种简单方法是定义一个接受Parameter::value 的单参数构造函数Parameter(double value)

#include <vector>
#include <optional>

struct Parameter
{  
    double value;
    std::optional<double> error;

    explicit Parameter(double v) : value(v)
    {}
};

那么你可以使用 range-constructor 如下:

DEMO

std::vector<Parameter> v_of_parameters(v_of_values.cbegin(), v_of_values.cend());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    相关资源
    最近更新 更多