【问题标题】:Transform Temporary Vector with Range-v3使用 Range-v3 转换临时向量
【发布时间】:2021-03-04 09:51:37
【问题描述】:

我一直在阅读有关 range-v3 视图、操作以及它们如何与临时集合交互的大量阅读资料,但我仍然觉得我缺少一些可以帮助我完成我认为应该工作的简单内容.

鉴于以下情况:

std::vector<int> get_vector() { return {1, 2, 3}; }

void func1()
{
  auto const v1 =
    get_vector() |
    ranges::view::transform([](auto const& i) { return i + 1; }) |
    ranges::to_vector;
}

我收到一条错误消息:

error: use of deleted function

还有一条值得阅读的好消息:

// **************************************************************************
// *    When piping a range into an adaptor, the range must satisfy the     *
// *    "viewable_range" concept. A range is viewable when either or both   *
// *    of these things are true:                                           *
// *      - The range is an lvalue (not a temporary object), OR             *
// *      - The range is a view (not a container).                          *
// **************************************************************************

这是有道理的,但我不想将get_vector 返回的向量保存到命名变量中。我不需要它。我只想要一个由transformto_vector 创建的新向量。

我不喜欢将临时变量分配给左值,因为我觉得它使它们合法化,而且在我看来,在这行代码之后,我希望临时向量被破坏。我不希望数据徘徊。我不希望它有名字。我不希望下一个开发者意外地认为他们可以使用它。

我认为最让我感动的部分是我觉得这应该有效。将临时变量传递给函数是 C++ 的基础。我想因为我没有创建一个我想保存的视图,所以 range-v3 可能是这个工作的错误库。

我尝试了其他几种我读过的组合。如ranges::views::cache1

void func1()
{
  auto const v1 =
    get_vector() |
    ranges::views::cache1 |
    ranges::views::transform([](auto const& i) { return i + 1; }) |
    ranges::to_vector;
}

但得到同样的错误。我尝试过的其他组合出现相同的错误:

void func1()
{
  auto const v1 =
    get_vector() |
    ranges::views::transform([](auto const& i) { return i + 1; }) |
    ranges::views::cache1 |
    ranges::to_vector;
}

还有:

void func1()
{
  auto const v1 =
    get_vector() |
    ranges::views::cache1 |
    ranges::views::transform([](auto const& i) { return i + 1; }) |
    ranges::views::cache1 |
    ranges::to_vector;
}

我尝试使用一个动作,但得到一个错误:

// *    When piping a range into an action, the range must be moved in.     *

这对我来说没有多大意义,因为临时向量已经是一个右值。

我错过了什么?我现在只是打地鼠。

【问题讨论】:

  • @AaronWright,这件事已经刺痛了我很多次。我只是认为这是一个设计缺陷!

标签: c++ range-v3


【解决方案1】:

正如错误消息所说,当将范围传递到适配器时,您需要范围是左值或视图。

get_vector 返回的临时向量不属于上述任一类别。一种解决方法是将其分配给左值,如下所示:

void func1()
{
    auto&& vec = get_vector();
    
    auto const v1 = 
      vec |
      ranges::views::transform([](auto const& i) { return i + 1; }) |
      ranges::to_vector;
}

这是demo

【讨论】:

  • 这确实有效,但是我不喜欢将临时变量分配给左值,因为我觉得它使它们合法化,并且在我看来,在这行代码之后,我希望临时向量破坏。我不希望数据徘徊。我不希望它有名字。我不希望下一个开发人员意外地认为他们可以使用它。我认为最让我感动的部分是我觉得这应该有效。将临时变量传递给函数是 C++ 的基础。我想因为我没有创建要保存 persay 的视图,所以 range-v3 可能是该工作的错误库。
  • @AaronWright 我不完全确定问题出在哪里。至于将临时限制在v1 的初始化,你可以做this。如果这就是你的意思,我可以编辑答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2020-07-26
  • 1970-01-01
相关资源
最近更新 更多