简体   繁体   English

从 std::vector 创建/填充 std::set 的 STL 方式

[英]STL way of creating/filling std::set from std::vector

I want to create and fill a set from the contents of a member variable of each entry of a vector .我想根据vector的每个条目的成员变量的内容创建并填充一个set This is what I am doing:这就是我正在做的:

struct S { int i; };

int main()
{
    std::vector<S*> structPtrs;

    // code to fill the above vector

    // create set from the above vector
    std::set<int> setInts;
    for (auto it = structPtrs.begin(); it != structPtrs.end(); ++it)
    {
        setInts.insert((*it)->i);
    }
}

Is there an STL way to do it?有STL方法吗? Or via any available method(s) in <algorithm> ?或者通过<algorithm>中的任何可用方法?

You can always apply std::transform from the range defined by the vector onto the "range" defined by an std::inserter :您始终可以将std::transform从向量定义的范围应用于 std:: std::inserter定义的“范围”:

transform(begin(structPtrs), end(structPtrs),
          inserter(setInts, end(setInts)), [] (S* s) {
  return s->i;
});

That should be more than enough use of the standard library.对标准库的使用应该绰绰有余了。


If you are willing to look beyond the standard library, there is also the option of using something like boost::transform_iterator , which will allow you to move the range transformation into the set's initialization:如果您愿意超越标准库,还可以选择使用类似boost::transform_iterator的东西,这将允许您将范围转换移动到集合的初始化中:

auto transfomer = [](S* s) { return s->i; };
std::set<int> setInts(
  boost::make_transform_iterator(begin(structPtrs), transfomer),
  boost::make_transform_iterator(end(structPtrs), transfomer)
);

You could use std::transform with an appropriate lambda and an insert iterator:您可以将std::transform与适当的 lambda 和插入迭代器一起使用:

std::transform(structPtrs.begin(), structPtrs.end(), std::inserter(setInts, setInts.end()),
    [](S* sp) { return sp->i; });

But personally, I find a simple range for loop to be much easier to follow:但就个人而言,我发现一个简单的循环范围更容易理解:

for (S* sp : structPtrs)
    setInts.insert(sp->i);

There is one other way you can do this.还有另一种方法可以做到这一点。 If you add conversion operator to int to your struct you can just use range constructor directly如果将转换运算符添加到int到结构中,则可以直接使用范围构造函数

#include <iostream>
#include <set>
#include <vector>
using namespace std;

struct test {int i; operator int() {return i;}};

int main() {
    vector<test> v;
        v.push_back(test{433});
        v.push_back(test{533});
        set<int> s(v.begin(), v.end());
        cout << *(++s.begin());
    return 0;
}

https://www.ideone.com/qJwtwc https://www.ideone.com/qJwtwc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM