Вы можете использовать std::transform
до , вставляя нужные элементы до myset
вместо использования operator int()
. ( Смотреть онлайн )
#include <algorithm> // std::transform
#include <iterator> // std::inserter
std::transform(myvector.cbegin(), myvector.cend()
, std::inserter(myset, myset.begin())
, [](const auto& cls) { return cls.get_a(); }
);
Достаточно общего?Хорошо, чтобы сделать его более универсальным, вы можете поместить его в функцию, в которой передается вектор из Myclass
, myset
для заполнения и указатель на функцию-член который нужно было назвать. ( Смотреть онлайн )
#include <algorithm> // std::transform
#include <iterator> // std::inserter
#include <functional> // std::invoke
#include <utility> // std::forward
using MemFunPtrType = int(Myclass::*)() const; // convenience type
void fillSet(const std::vector<Myclass>& myvector, std::set<int>& myset, MemFunPtrType func)
{
std::transform(myvector.cbegin(), myvector.cend()
, std::inserter(myset, myset.begin())
, [func](const Myclass& cls) {
return (cls.*func)();
// or in C++17 simply invoke the func with each instace of the MyClass
// return std::invoke(func, cls);
}
);
}
Или полностью универсальным, используя шаблоны , можно: ( Смотреть вживуюонлайн )
template<typename Class, typename RetType, typename... Args>
void fillSet(const std::vector<Class>& myvector
, std::set<RetType>& myset
, RetType(Class::*func)(Args&&...)const
, Args&&... args)
{
std::transform(myvector.cbegin(), myvector.cend()
, std::inserter(myset, myset.begin())
, [&](const Myclass& cls) { return std::invoke(func, cls, std::forward<Args>(args)...); }
);
}
Теперь вы заполните myset
как.
fillSet(myvector, myset, &Myclass::get_a); // to fill with member a
fillSet(myvector, myset, &Myclass::get_b); // to fill with member b
Вот полный рабочий пример:
#include <iostream>
#include <vector>
#include <set>
#include <algorithm> // std::transform
#include <iterator> // std::inserter
#include <functional> // std::invoke
#include <utility> // std::forward
class Myclass
{
int member_a;
int member_b;
public:
Myclass(int a_init, int b_init) : member_a{ a_init }, member_b{ b_init } {};
int get_a() const noexcept { return member_a; }
int get_b() const noexcept { return member_b; }
};
template<typename Class, typename RetType, typename... Args>
void fillSet(const std::vector<Class>& myvector
, std::set<RetType>& myset
, RetType(Class::*func)(Args&&...)const
, Args&&... args)
{
std::transform(myvector.cbegin(), myvector.cend()
, std::inserter(myset, myset.begin())
, [&](const Myclass& cls) { return std::invoke(func, cls, std::forward<Args>(args)...); }
);
}
int main()
{
auto myvector = std::vector<Myclass>({ {1, 0}, {2, 0}, {2, 0}, {3, 0} });
std::set<int> myset;
std::cout << "Filling with member a\n";
fillSet(myvector, myset, &Myclass::get_a);
for (auto element : myset) std::cout << "element: " << element << "\n";
std::cout << "Filling with member b\n";
myset.clear();
fillSet(myvector, myset, &Myclass::get_b);
for (auto element : myset) std::cout << "element: " << element << "\n";
}
Вывод :
Filling with member a
element: 1
element: 2
element: 3
Filling with member b
element: 0