【问题标题】:Add element to function in place C++将元素添加到功能 C++
【发布时间】:2021-02-06 05:32:10
【问题描述】:

将元素添加到功能 C++ Python代码:

l1 = [1, 2, 3]
l2 = l1 + [4]
print(l2) #[1, 2, 3, 4]

l3 = l1+l2
print(l3) #[1, 2, 3, 1, 2, 3, 4]

有没有办法在 C++ 中做到这一点

【问题讨论】:

标签: c++ vector


【解决方案1】:

您在评论中澄清说您想“就地”执行此操作。在 C++17 中,标准库中没有用于连接两个向量(或容器)的运算符或函数,但自己创建一个非常容易:

template <class T>
std::vector<T> concat(const std::vector<T>& v1, const std::vector<T>& v2)
{
    auto res = v1;
    res.insert(res.end(), v2.begin(), v2.end());
    return res;
}

在 C++20 中,所有这些都发生了变化,因为我们将获得范围。

在此之前,您可以使用 range-v3 库(标准范围所基于的库):

views::concat(v1, v2);

这会返回一个范围。这应该足够了,因为您应该将范围视图作为参数或至少作为迭代器。优点是视图是 惰性的。在您迭代它们并且不创建新容器之前,它们不会进行实际的转换。如果你仍然需要一个向量,你可以这样做:

#include <range/v3/view.hpp>

using namespace ranges;

auto test()
{

    std::vector v1{10, 20, 30};
    std::vector v2{1, 2, 3, 4, 5};

    auto v = views::concat(v1, v2) | to<std::vector>();
}

有一条评论是关于创建一个重载的 operator+ 而不是函数。出于以下几个原因,这将是一个坏主意:

重载仅使用标准类作为参数的运算符是一个坏主意,因为您无法打开命名空间 std 来在那里定义它并在其他地方定义它会导致 ADL 出现问题。

其次,即使可以,一条黄金法则是重载运算符以执行预期的操作。在这种情况下,(一些/大多数)人会期望 operator+ 进行元素相加。

【讨论】:

  • 代替/除了concat(),它也可能是一个重载的运算符+,不是吗?我曾经摆弄过类似的东西(为了好玩):set intersection/union operators.
  • @Scheff:是的,它可以——但这几乎可以肯定是个坏主意,因为许多(大多数?)人可能会认为x + y 会进行成对添加(即, result[n] = x[n] + y[n];)。但是+ 在应用于std::string 时会执行您所描述的操作,毫无疑问,如果您真的想这样做,std::vector 也可以正常工作。
  • @JerryCoffin 我明白了。有趣的是,Python 的人没有这个担心...... ;-) (也许,因为它(被认为是)Python 中的列表。)
  • @Scheff:C++ 和 Python 之间有很多不同之处,包括使用它们的人的期望。
  • @Scheff python 是一种与 C++ 非常不同的语言。当您习惯于一种语言时,您可能会很想像对待您熟悉的那种语言一样对待所有其他语言,但尝试将每种语言都视为自己的语言。每种语言都有长处和短处。
【解决方案2】:

我相信您正在尝试在 c++ 中向向量添加元素。

vector<int> v;       // { }
v.push_back(10);     // { 10 }

要将一个向量附加到另一个向量,可以使用 insert

vector<int> v = { 11, 12 }; 
vector<int> v2 = { 13, 14 }; 

v.insert(v.end(), v2.begin(), v2.end());     // { 11, 12, 13, 14 }

要插入的第一个参数是一个迭代器,指向您希望插入第二个向量元素的位置。第二个和第三个参数是指向第二个向量开始和结束的迭代器,它们表示将哪些元素插入第一个向量的边界。

此操作有效地将第二个向量附加到第一个向量中。

【讨论】:

  • 这个可以在同一行使用吗? myFunc(v.insert(v.end(), v2.begin(), v2.end()))
  • 是的,但是 v.insert 返回“指向第一个新插入元素的迭代器”。所以你的 myFunc 需要接受它作为参数。你想做什么?
  • 抱歉造成混淆,但“myFunc(v.insert(v.end(), v2.begin(), v2.end()))”是实际语法的伪代码跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多