【问题标题】:One liner for inserting some particular value of class object一种用于插入类对象的某些特定值的衬垫
【发布时间】:2019-03-01 02:44:33
【问题描述】:

假设我有一个 vector<int> myVec; 并且我想将它转换为一个集合,我可以有一个单衬-

set<int> mySet(myVec.begin(), myVec.end());

这很容易找到。

现在我有vector&lt;pair&lt;int, int&gt;&gt;,我想获得每对中第二个值的集合。我应该如何使用集合构造函数来实现这一点?有可能吗?

假设我有 C++11、C++14、C++17。

另外,如果我能获得一些关于如何对不同容器进行一般意义上的类似调整的信息,我将不胜感激。

【问题讨论】:

  • 期待看到聪明的答案,我可能会为向量编写一个自定义迭代器,当取消引用时返回 second,尽管这不会是一个单行;)

标签: c++ set c++14 std c++17


【解决方案1】:

在这种情况下要求单线不可避免地会导致range-v3的解决方案:

#include <range/v3/view/map.hpp>

const std::vector<std::pair<int, int>> myVec{{1, 10}, {2, 20} , {3, 30}};
const std::set<int> mySet = myVec | ranges::view::values;

Boost range¹ 类似的方法:

#include <boost/range/adaptor/map.hpp>

using boost::adaptors::map_values;
const auto mySet = boost::copy_range<std::set<int>>(myVec | map_values); 

不过,您可能认为这种方法最简单(无需库,但需要 C++17):

for (const auto& [first, second] : myVec)
    mySet.insert(second);

¹ 感谢 @Caleth 提出改进 cmets 的建议。

【讨论】:

  • 这太棒了。范围 API 真的很酷,我希望它尽快成为标准。
  • 它隐藏在iterator_range的文档中
  • @Caleth 这确实符合隐藏的条件。
【解决方案2】:

这个几乎是单行的应该适合你:

#include <algorithm>
#include <iterator>
#include <iostream>
#include <set>
#include <utility>
#include <vector>

int main()
{
    std::vector<std::pair<int, int>> myVec = { {1, 2}, {3, 4} };
    std::set<int> mySet;
    std::transform(myVec.begin(), myVec.end(), std::inserter(mySet, mySet.begin()),
                   [](const std::pair<int, int>& elem) { return elem.second; });
    for (int value : mySet)
    {
        std::cout << value << std::endl;
    }
    return 0;
}

输出:

2
4

【讨论】:

  • 我认为这是最好的你可以使用标准 C++,但这仍然不是单行的
  • 值得注意的是,您使用 transform 的“单行”比等效的 for-loop/insert 长得多。假设具有结构化绑定的正常间距和全名... 143 个字符与 69 个字符。
  • @Barry 是的,这是真的。我并不是说这一定比循环更可取,但我认为 OP 正在寻找解决问题的“功能性”解决方案。
  • @jdehesa 是的,我也不认为transform 是一个实用的解决方案。 ¯\_(ツ)_/¯
【解决方案3】:

执行此操作的最 C++y 方法可能是定义一个仅生成第二个值的自定义迭代器类型。

您可以使用与更常见的查询非常相似的代码,即从地图中获取值:iterator adapter to iterate just the values in a map?

或者,你知道,只是写一个循环。没有错。

【讨论】:

    猜你喜欢
    • 2017-07-05
    • 2021-11-06
    • 2017-04-12
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 2014-08-13
    相关资源
    最近更新 更多