Tuple reinforcement + transform

Is it possible to do the following?

Say my boot tuple has <std::string, T>

I would like to use std :: transform + mem_fun to insert only the std :: string element into the corresponding vector. Is it possible, or should we use a loop and push_back (get <0>) ...

Those. The following does not like to compile ... (unknown types ...)

 result.resize(storage.size()) std::transform(storage.begin(), storage.end(), result.begin(), std::mem_fun(&boost::get<0>)); 

Here is an example (trying one of the comments):

 #include <boost/tuple/tuple.hpp> #include <vector> #include <string> #include <algorithm> #include <boost/bind.hpp> template <typename T> class TestClass { private: typedef boost::tuple<std::string,T> PairType; std::vector<PairType> storage; public: void extract(std::vector<std::string> &result) { result.resize(storage.size()); std::transform(storage.begin(), storage.end(), result.begin(), boost::bind(&PairType::get<0>, _1)); } }; int main(int argc, char**argv) { TestClass<int> bb; std::vector< std::string> result; bb.extract(result); return 0; } g++ test.cpp test.cpp: In member function `void TestClass<T>::extract(std::vector<std::string, std::allocator<std::string> >&)': test.cpp:17: error: expected primary-expression before ',' token test.cpp: In member function `void TestClass<T>::extract(std::vector<std::string, std::allocator<std::string> >&) [with T = int]': test.cpp:26: instantiated from here test.cpp:17: error: address of overloaded function with no contextual type information 
+4
source share
2 answers

The type of overloads get<0> you want:

 const std::string& (*)(const boost::tuples::cons<std::string, boost::tuples::cons<int, boost::tuples::null_type> >&) 

If you typedef to get0_fn_t , then you can declare a pointer to this overload get<0> with:

 get0_fn_t getter_fn = &boost::tuples::get<0, std::string, boost::tuples::cons<int, boost::tuples::null_type> >; 

EDIT: This program is a complete working example:

 #include <algorithm> #include <cstdlib> #include <iostream> #include <iterator> #include <string> #include <vector> #include <boost/bind.hpp> #include <boost/tuple/tuple.hpp> int main() { typedef boost::tuple<std::string, int> tuple_type; std::vector<tuple_type> tuples; tuples.push_back(boost::make_tuple(std::string("test3"), 3)); tuples.push_back(boost::make_tuple(std::string("test0"), 0)); std::vector<std::string> strings; typedef const std::string& (*get0_fn_t)(const boost::tuples::cons<std::string, boost::tuples::cons<int, boost::tuples::null_type> >&); get0_fn_t getter_fn = &boost::tuples::get<0, std::string, boost::tuples::cons<int, boost::tuples::null_type> >; std::transform(tuples.begin(), tuples.end(), std::back_insert_iterator<std::vector<std::string> >(strings), getter_fn); std::vector<std::string>::const_iterator it, end = strings.end(); for (it = strings.begin(); it != end; ++it) std::cout << *it << std::endl; return EXIT_SUCCESS; } 

EDIT2: This shows how to integrate it into the TestClass template:

 template <typename T> class TestClass { private: typedef boost::tuple<std::string, T> PairType; std::vector<PairType> storage; public: void extract(std::vector<std::string>& result) const { result.clear(); typedef const std::string& (*get0_fn_t)(const boost::tuples::cons<std::string, boost::tuples::cons<T, boost::tuples::null_type> >&); get0_fn_t getter_fn = &boost::tuples::get<0, std::string, boost::tuples::cons<T, boost::tuples::null_type> >; std::transform(storage.begin(), storage.end(), result.begin(), getter_fn); } }; 
+1
source

Use the get member version and Boost.Bind. I tested this and it works for what it is worth.

 #include <algorithm> #include <iostream> #include <iterator> #include <string> #include <vector> #include <boost/bind.hpp> #include <boost/tuple/tuple.hpp> int main() { typedef boost::tuple<std::string,int> T; std::vector<T> v1; v1.push_back(T("Blah", 23)); v1.push_back(T("Wibble", 9)); std::vector<std::string> v2; std::transform(v1.begin(), v1.end(), std::back_inserter(v2), boost::bind(&T::get<0>, _1)); std::copy(v2.begin(), v2.end(), std::ostream_iterator<std::string>(std::cout, "\n")); return 0; } 
+3
source

Source: https://habr.com/ru/post/1335346/


All Articles