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

时间:2018-03-08 06:27:21

标签: c++ c++11 stl stdvector stdset

我想从set的每个条目的成员变量的内容中创建并填充vector。这就是我在做的事情:

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);
    }
}

有STL方式吗?或者通过<algorithm>中的任何可用方法?

3 个答案:

答案 0 :(得分:4)

您可以将std::transform与适当的lambda和插入迭代器一起使用:

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

但就个人而言,我发现循环的简单范围更容易理解:

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

答案 1 :(得分:3)

您始终可以将std::transform从矢量定义的范围应用到&#34;范围&#34;由std::inserter定义:

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

这应该足以使用标准库。

如果您愿意超越标准库,还可以使用类似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)
);

答案 2 :(得分:1)

还有另外一种方法可以做到这一点。如果将转换运算符添加到结构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