【问题标题】:Convert temporary vector to list in C++在 C++ 中将临时向量转换为列表
【发布时间】:2020-09-01 09:45:29
【问题描述】:

我有一个函数get_stuff(),它返回一个vector。 我想做以下事情:

vector<int> get_stuff();  // a function returning a vector of ints

list<int> stuff = get_stuff();

stuff 必须是一个列表,因为会有很多插入/删除操作。

但是您显然不能将vector 分配给list,也不能将其用作构造函数参数。

另外,我宁愿不只是将get_stuff 的返回类型更改为list,因为在代码的其他部分我需要随机访问get_stuff 返回的内容,因此我需要vector

显而易见的方法是:

vector<int> get_stuff();  // a function returning a vector of ints

vector<int> stuff_temp = get_stuff();

list<int> stuff(stuff_temp.begin(), stuff_temp.end());

但除非绝对必要,否则我宁愿不要用不必要的变量污染代码。

有没有更好的方法将get_stuff 的返回值放入列表stuff,最好是一行?

【问题讨论】:

  • 不能get_stuff 只返回一个list 吗?关于不必要的变量:您可以将整个内容包装在辅助函数 std::list&lt;int&gt; get_stuff_as_list() 或其他东西中。
  • 我更好奇你需要一个列表开始的原因。你想解决的原始问题是什么?为什么需要一个列表来解决这个问题?
  • @Someprogrammerdude 正如我在问题中所说。会有很多删减。为了保持代码干净,删除将与填充容器的代码分开(无论该容器是什么)。此外,为了保持代码干净,可能导致元素被过滤掉的多个条件将被分开。因此,这将导致相当多的随机访问删除。
  • 如果您有一个庞大的列表,那么在std::list 中插入/删除比std::vector 更有效,对吧?因为您需要从插入/删除位置推/拉到结束?
  • 虽然std::vector 通常应该是“转到”容器类型,但也许从这里开始不是最好的选择?也许您应该从一个列表开始,并避免容器类型之间的所有复制?或者也许考虑“介于两者之间”(某种)std::deque

标签: c++ visual-c++ stl


【解决方案1】:

您可以像这样使用 lambda:

std::list<int> oList = [](std::vector<int>&& v){ return std::list<int>(v.begin(), v.end()); }(get_stuff());

这行可以写得短一点:

auto oList = [](std::vector<int>&& v){ return std::list<int>(v.begin(), v.end()); }(get_stuff());

C++14 更短:

auto oList = [](auto&& v){ return std::list<int>(v.begin(), v.end()); }(get_stuff());

【讨论】:

  • range-for 也可以吗? list&lt;int&gt; stuff; for ( int i : get_stuff() ) stuff.push_back( i );?
  • @DevSolar,是的,您可以通过这种方式使用 range-for 循环,但不能使用这种方式:for( int i : get_stuff().some_func() ) { /* .. */ } 请参阅link
【解决方案2】:

这样的事情可能会起作用...除了临时变量之外没有其他变量.. :)

vector<int> v = {1, 2, 3};
list<int> l(3);
std::copy(v.begin(), v.end(), l.begin());

【讨论】:

  • 我已经在问题中谈到了这一点。我不想使用临时变量。把这个问题再读一遍:)
【解决方案3】:

我决定使用模板:

template <typename CONTAINER_TYPE> 
CONTAINER_TYPE get_stuff() 
{
    CONTAINER_TYPE output;
    output.push_back(thing1);
    output.push_back(thing2);
    output.push_back(thing2);
    return output;
}

list<int> stuff = get_stuff<list<int>>();

这提供了我需要的所有优势。如果容器类型不支持我需要的操作并且它可以使用任何容器,则会在编译时抛出错误。

【讨论】:

  • 如果get_stuff() 返回您问题中提出的向量,这将如何工作?
  • 这不是您自己问题的答案。
  • @DevSolar 抱歉!我认为它已经足够清楚了,我对函数内部的外观进行了编辑。
  • 确实意识到,一旦您将其编写为不是模型而是实际可行的解决方案,您将仍然使用临时变量(一个函数调用几行不必要的源码)?这是如何解决您的问题的?
  • @DevSolar 我可能误解了你的意思。 get_stuff() 基本上看起来一样,我用模板CONTAINER_TYPE 替换了vector&lt;thing&gt; 并且基本上没有改变。所以我描述的问题似乎已经解决,因为我现在不需要额外的变量,只需将函数结果分配给我的list。我是否遗漏或误解了什么?
猜你喜欢
  • 1970-01-01
  • 2011-07-07
  • 2021-12-25
  • 2019-01-29
  • 2019-03-02
  • 1970-01-01
相关资源
最近更新 更多