I'd like to use std::make_pair usable with e.g. std::bind2nd so that I get an unary function object which I could use with e.g. std::transform.
Right now I'm using
template <typename T, typename U>
struct pair_creator : std::binary_function<T, U, std::pair<T, U> >
{
std::pair<T, U> operator()( T arg1, U arg2 ) const {
return std::make_pair( arg1, arg2 );
}
};
// ...
std::transform( start1, end2, start2, std::bind2nd( pair_creator<int, bool>(), true ) );
but I wonder - is there an easier way to make std::make_pair (or potentially any other binary function) usable with the binders except by writing little wrapper classes like pair_creator by hand?
I'd need a C++03 solution (for some obscure reason, stackoverflow always rewrites my c++0x tag to c++11 when saving the post...).
You need std::ptr_fun, which turns a plain function pointer into an adaptable binary function object (or a unary function object, if you pass it a one-arg function):
#include <functional>
#include <utility>
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> intvec;
intvec.push_back(0);
intvec.push_back(1);
std::vector<std::pair<int,bool> > pairvec(intvec.size());
std::transform(
intvec.begin(),
intvec.end(),
pairvec.begin(),
// this is the significant line
std::bind2nd(std::ptr_fun(std::make_pair<int, bool>), true)
);
std::cout << pairvec[1].first << " " << pairvec[1].second << "\n";
}
ptr_fun is declared:
template <class Arg1, class Arg2, class Result>
pointer_to_binary_function<Arg1,Arg2,Result>
ptr_fun(Result (*)(Arg1,Arg2));
And for the unary version:
template <class Arg, class Result>
pointer_to_unary_function<Arg,Result>
ptr_fun(Result (*)(Arg));
Use lambda don't need to use bind adaptor.
std::vector<int> start1 = list_of(1)(2)(3)(4)(5);
std::vector<int> start2 = list_of(10)(20)(30)(40)(50);
std::vector<Pair> w_vecofpair; // vector of pair
w_vofpair.reserve(start1.size());
// create pair using lambda
std::transform( std::begin(start1), std::end(start1), std::begin(start2), // ranges
std::back_inserter(w_vecofpair), // result
[](int a,int b) { return std::make_pair(a,b);}); // pair creator
for (auto& pairInt : w_vecofpair)
{
std::cout << pairInt << "\n";
}
// bind 2nd arg to some value, say 2
std::transform( std::begin(start1), std::end(start1), std::begin(start2),
std::back_inserter(w_vecofpair), [](int a, int b) { return std::make_pair(a,2);});
for (auto& second : w_vecofpair | map_values)
{
std::cout << "The second value of our bind 2nd is: " << second << "\n";
assert(second==2);
}
Related
Hi is there a container where a key is a typename and value is an object/instance in boost or std???
What I want to achieve is I have a object pool for each data type and when I want to construct that object I want to just fetch by Key. I already have working code but I would be happier if i used something more standard.
Currently I have a code like this:
template<size_t index, size_t counter, typename T0, typename ...T>
struct PoolBuilderInternal
{
typedef typename boost::mpl::insert<
typename PoolBuilderInternal<index - 1, counter + 1, T...>::m
, boost::mpl::pair<T0, std::integral_constant<size_t, counter> > >::type m;
};
template<size_t counter, typename T0, typename ...T>
struct PoolBuilderInternal<1, counter, T0, T...>
{
typedef typename boost::mpl::map<boost::mpl::pair<T0, std::integral_constant<size_t, counter> > > m;
};
template<typename ...T>
struct Pools
{
std::tuple<
boost::object_pool<T>...> m_pools;
typedef typename PoolBuilderInternal<sizeof...(T), 0, T...>::m poolType;
template<typename T>
boost::object_pool<T>& GetPool()
{
return std::get< boost::mpl::at<poolType, T>::type::value>(m_pools);
}
};
Pools<int, std::string, int64_t> m_pools;
m_pools.Get<int>();
EDIT: What I want is a COMPILE-TIME map. You can imagine a std::tuple<> but some that wouldnt not be accessed by index std::get<0,1,2>... but rather by a key (?std::tuple_map)
If types in the pool are unique use c++ 14 std::get< T >(std::tuple(s))
#include <iostream>
#include <string>
#include <tuple>
struct A
{
int value = 17;
};
int main()
{
auto t = std::make_tuple(1, std::string{"Foo"}, 3.14, A{});
std::cout << "(" << std::get<int>(t) << ", "
<< std::get<std::string>(t)
<< ", " << std::get<double>(t)
<< ", " << std::get<A>(t).value << ")\n";
}
If I understand this question right (and I'm not sure I do), what you really want is some kind of class factory, and that, in various forms, is a well-known design pattern because it allows users of the factory to construct objects whose constructors (and indeed types, quite often, when a class hierarchy is involved) are unknown or off-limits to them.
On that basis, I humbly offer you the following proof-of-concept code. Please note that I threw this together in rather a hurry and it's probably not optimal. I'm sure more is possible, including passing parameters to the relevant constructors to make_string() and make_foo() from the call site (e.g. factory [t_string] ("My string"). I'll look into that when I have time, if you show any interest in this post.
OK, so here's your class factory. You should be able to apply it to any types, including boost types. As coded, any parameters that need to be passed to the object in question are currently defined when the factory function (e.g. make_string) is added to the map (which is probably not ideal). These factory functions also could / should be lambdas. Again, I'll add that in later.
#include <functional>
#include <unordered_map>
#include <variant>
#include <iostream>
struct Foo
{
Foo (int x) : x (x) { }
int x;
};
enum ObjectType { t_string, t_foo }; // ...
using all_possible_types = std::variant <std::string, Foo>; // ...
static all_possible_types make_string (const std::string& s)
{
std::cout << "make_string " << s << "\n";
return all_possible_types (std::string (s));
}
static all_possible_types make_foo (int x)
{
std::cout << "make_foo " << x << "\n";
return all_possible_types (Foo (x));
}
// ...
int main()
{
std::unordered_map <ObjectType, std::function <all_possible_types ()>> factory;
factory.insert ({t_string, std::bind (make_string, "Initial string value")});
factory.insert ({t_foo, std::bind (make_foo, 42)});
// ...
all_possible_types variant_string = factory [t_string] ();
std::cout << std::get <std::string> (variant_string) << "\n\n";
all_possible_types variant_foo = factory [t_foo] ();
std::cout << std::get <Foo> (variant_foo).x << "\n";
}
Output:
make_string Initial string value
Initial string value
make_foo 42
42
Live demo.
As I say, this doesn't look like much now but I will improve it later. In the meantime, I suggest you take a look at it to get your head around what I'm doing here.
I found std::invoketo call every callable object with a set of parms and std::apply to expand a tuple as parms to a callable.
Is there a combination of both which enables to invoke any callable with a tuple as parms?
#include <iostream>
#include <tuple>
#include <functional>
class A
{
private:
int n;
public:
A( int _n ): n(_n){}
void operator()(int x, double y )
{
std::cout << n << " " << x << " " << y << std::endl;
}
void MemFun( int x, double y )
{
std::cout << n << " " << x << " " << y << std::endl;
}
};
int main()
{
A a(100);
std::invoke( a, 10, 1.23 );
auto parm2 = std::make_tuple( 1,2.34);
std::apply ( a, parm2 );
std::invoke ( &A::MemFun, a, 4, 5.67 );
// ???
std::??apply_invoke?? ( &A::MemFun, a, parm2 );
}
Do you mean something like this?
std::apply(&A::MemFun, std::tuple_cat(std::make_tuple(a), parm2));
Is there a combination of both which enables to invoke any callable with a tuple as parms?
std::apply can be used to invoke any callable, so I'm not really understanding the problem here. It's just like std::invoke for member functions: The first parameter needs to be the object you want to call the function on. Same goes for std::apply, where the first element of the passed tuple needs to be the object you want it to be called on.
If you don't like specifying std::tuple_cat and such, you can always create a wrapper:
template<typename F, typename T, typename U>
decltype(auto) apply_invoke(F&& func, T&& first, U&& tuple) {
return std::apply(std::forward<F>(func), std::tuple_cat(std::forward_as_tuple(std::forward<T>(first)), std::forward<U>(tuple)));
}
How about std::apply( std::bind(&A::MemFun, &a, std::placeholders::_1, std::placeholders::_2), parm2 );?
Edited to include suggestions and placeholders
Assuming I have struct and std::tuple with same type layout:
struct MyStruct { int i; bool b; double d; }
using MyTuple = std::tuple<int,bool,double>;
Is there any standartized way to cast one to another?
P.S. I know that trivial memory copying can do the trick, but it is alignment and implementation dependent
We can use structured bindings to convert a struct into a tuple with a bit of work.
Struct-to-tuple is very awkward.
template<std::size_t N>
struct to_tuple_t;
template<>
struct to_tuple_t<3> {
template<class S>
auto operator()(S&& s)const {
auto[e0,e1,e2]=std::forward<S>(s);
return std::make_tuple(e0, e1, e2);
}
};
Now, write a to_tuple_t for each size you want to support. This gets tedious. Sadly I know of no way to introduce a parameter pack there.
template<std::size_t N, class S>
auto to_tuple(S&& s) {
return to_tuple_t<N>{}(std::forward<S>(s));
}
I know of no way to calculate the value of N required either. So you'd have to type the 3 in auto t = to_tuple<3>(my_struct); when you call it.
I am not a master of structured bindings. There is probably a && or & or a decltype that would permit perfect forwarding on these lines:
auto[e0,e1,e2]=std::forward<S>(s);
return std::make_tuple(e0, e1, e2);
but without a compiler to play with, I'll be conservative and make redundant copies.
Converting a tuple into a struct is easy:
template<class S, std::size_t...Is, class Tup>
S to_struct( std::index_sequence<Is...>, Tup&& tup ) {
using std::get;
return {get<Is>(std::forward<Tup>(tup))...};
}
template<class S, class Tup>
S to_struct( Tup&&tup ) {
using T=std::remove_reference_t<Tup>;
return to_struct(
std::make_index_sequence<std::tuple_size<T>{}>{},
std::forward<Tup>(tup)
);
}
SFINAE support based off tuple_size might be good for to_struct.
The above code works with all tuple-likes, like std::pair, std::array, and anything you custom-code to support structured bindings (tuple_size and get<I>).
Amusingly,
std::array<int, 3> arr{1,2,3};
auto t = to_tuple<3>(arr);
works and returns a tuple with 3 elements, as to_tuple is based on structured bindings, which work with tuple-likes as input.
to_array is another possibility in this family.
Unfortunately there is no automatic way to do that, BUT an alternative is adapt the struct to Boost.Fusion sequence. You do this once and for all for each new class.
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
...
struct MyStruct { int i; bool b; double d; }
BOOST_FUSION_ADAPT_STRUCT(
MyStruct,
(int, i)
(bool, b)
(double, d)
)
The use MyStruct as if it where a Fusion.Sequence (it fits generically almost everywhere you already use std::tuple<...>, if you make those functions generic.) As a bonus you will not need to copy your data members at all.
If you really need to convert to std::tuple, after "Fusion-adapting" you can do this:
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/algorithm/transformation/zip.hpp>
...
auto to_tuple(MyStruct const& ms){
std::tuple<int, bool, double> ret;
auto z = zip(ret, ms);
boost::fusion::for_each(z, [](auto& ze){get<0>(ze) = get<1>(ze);});
// or use boost::fusion::copy
return ret;
}
The truth is that std::tuple is a half-backed feature. It is like having STD containers and no algorithms. Fortunatelly we have #include <boost/fusion/adapted/std_tuple.hpp> that allows us to do amazing things.
Full code:
By including the std_tuple.hpp header from Boost.Fusion std::tuple is automatically adapted to a Boost.Fusion sequence, thus the following is possible by using Boost.Fusion as a bridge between your struct and std::tuple:
#include <iostream>
#include <string>
#include <tuple>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/algorithm/auxiliary/copy.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
struct foo
{
std::string a, b, c;
int d, e, f;
};
BOOST_FUSION_ADAPT_STRUCT(
foo,
(std::string, a)
(std::string, b)
(std::string, c)
(int, d)
(int, e)
(int, f)
)
template<std::size_t...Is, class Tup>
foo to_foo_aux(std::index_sequence<Is...>, Tup&& tup) {
using std::get;
return {get<Is>(std::forward<Tup>(tup))...};
}
template<class Tup>
foo to_foo(Tup&& tup) {
using T=std::remove_reference_t<Tup>;
return to_foo_aux(
std::make_index_sequence<std::tuple_size<T>{}>{},
std::forward<Tup>(tup)
);
}
template<std::size_t...Is>
auto to_tuple_aux( std::index_sequence<Is...>, foo const& f ) {
using boost::fusion::at_c;
return std::make_tuple(at_c<Is>(f)...);
}
auto to_tuple(foo const& f){
using T=std::remove_reference_t<foo>;
return to_tuple_aux(
std::make_index_sequence<boost::fusion::result_of::size<foo>::type::value>{},
f
);
}
int main(){
foo f{ "Hello", "World", "!", 1, 2, 3 };
std::tuple<std::string, std::string, std::string, int, int, int> dest = to_tuple(f);
// boost::fusion::copy(f, dest); // also valid but less general than constructor
std::cout << std::get<0>(dest) << ' ' << std::get<1>(dest) << std::get<2>(dest) << std::endl;
std::cout << at_c<0>(dest) << ' ' << at_c<1>(dest) << at_c<2>(dest) << std::endl; // same as above
foo f2 = to_foo(dest);
std::cout << at_c<0>(f2) << ' ' << at_c<1>(f2) << at_c<2>(f2) << std::endl;
}
I will not recommend reinterpret_cast<std::tuple<...>&>(mystructinstance.i) because that will result in negative votes and it is not portable.
Is there any standartized way to cast one to another?
There is no way to "cast" the one to the other.
The easiest may be to use a std::tie to pack the tuple out into the struct;
struct MyStruct { int i; bool b; double d; };
using MyTuple = std::tuple<int,bool,double>;
auto t = std::make_tuple(42, true, 5.1);
MyStruct s;
std::tie(s.i, s.b, s.d) = t;
Demo.
You can further wrap this up in higher level macros or "generator" (make style) functions, e.g;
std::tuple<int, bool, double> from_struct(MyStruct const& src)
{
return std::make_tuple(src.i, src.b, src.d);
}
MyStruct to_struct(std::tuple<int, bool, double> const& src)
{
MyStruct s;
std::tie(s.i, s.b, s.d) = src;
return s;
}
I know that trivial memory copying can do the trick, but it is alignment and implementation dependent?
You mention the "trivial memory copy" would work - only for copying the individual members. So basically, a memcpy of the entire structure to the tuple and vice-versa is not going to always behave as you expect (if ever); the memory layout of a tuple is not standardised. If it does work, it is highly dependent on the implementation.
Tuple to struct conversion is trivial, but backward I think is impossible at current C++ level in general.
#include <type_traits>
#include <utility>
#include <tuple>
namespace details
{
template< typename result_type, typename ...types, std::size_t ...indices >
result_type
make_struct(std::tuple< types... > t, std::index_sequence< indices... >) // &, &&, const && etc.
{
return {std::get< indices >(t)...};
}
}
template< typename result_type, typename ...types >
result_type
make_struct(std::tuple< types... > t) // &, &&, const && etc.
{
return details::make_struct< result_type, types... >(t, std::index_sequence_for< types... >{}); // if there is repeated types, then the change for using std::index_sequence_for is trivial
}
#include <cassert>
#include <cstdlib>
int main()
{
using S = struct { int a; char b; double c; };
auto s = make_struct< S >(std::make_tuple(1, '2', 3.0));
assert(s.a == 1);
assert(s.b == '2');
assert(s.c == 3.0);
return EXIT_SUCCESS;
}
Live example.
I have following question about std::experimental::apply. From what I understand it takes function object and tuple, and than expands the tuple into parameter pack, which is applied to given functor. Unluckily, I have type mismatch in the code below when I try to compile (function invocation).
template<std::size_t population_size, std::size_t generations, typename Func,
class Compare=std::greater<>,
class Generator=std::default_random_engine,
class Distribution=std::uniform_real_distribution<>>
constexpr auto optimize(Func function, const std::pair<auto,auto>... range){ //CHECKING IF FUNCTION IS A FUNCTOR, TBD!
static_assert(sizeof...(range)>2, "Function needs at least two arguments");
//RANDOM NUMBER GENERATOR AND CHECKING ARITHMETIC TYPES
constexpr decltype(auto) generate_number=[&](std::pair<auto,auto> range){
static_assert(std::is_arithmetic<std::tuple_element_t<0, decltype(range)>>(),
"First argument of std::pair has to be arithmetic!");
static_assert(std::is_arithmetic<std::tuple_element_t<1, decltype(range)>>(),
"Second argument of std::pair has to be arithmetic!");
return std::bind(Distribution(range.first,range.second),Generator());
};
//SINGLE RANDOM INDIVIDUAL GENERATOR
decltype(auto) generate_random_individual=[&](){ //RUN THIS FUNCTION ASYNCHRONOUSLY, TBD!
auto genotype=std::make_tuple(generate_number(range)()...); //WORKS FINE
//CRITICAL FUNCTION AND THE TOPIC OF THIS POST
auto key=std::experimental::apply(function,genotype);
//CRITICAL FUNCTION AND THE TOPIC OF THIS POST
//return std::make_pair(key,genotype);
};
generate_random_individual();
}
Here is my test case (should compile fine without experimental::apply).
#include<utility>
#include<iostream>
#include"optimalization.hpp"
class Function{
public:
Function()=default;
double operator()(double x, double y, double z){
return (std::exp(x+1.25)*std::pow(y,z))/std::exp((x*y)/z);
}
};
int main(){
Function f{};
double x=optimize<100, 200>(f, std::make_pair(-21, 37), std::make_pair(22.5, 88.11), std::make_pair(-13, 37));
std::cout << x << std::endl;
}
The core of the problem is that Function::operator() is not const. There are some other issues, such as constexpr auto optimize(Func function, const std::pair<auto, auto>... range) being invalid syntax, but those basically fall into place once the main issue is fixed.
Working code:
#include <cstddef>
#include <functional>
#include <random>
#include <experimental/tuple>
#include <type_traits>
#include <utility>
template<
std::size_t population_size, std::size_t generations,
typename Func,
typename Compare = std::greater<>,
typename Generator = std::default_random_engine,
typename Distribution = std::uniform_real_distribution<>,
typename... RangeElemT
>
auto optimize(Func function, std::pair<RangeElemT, RangeElemT> const... range) {
static_assert(sizeof...(range) > 2, "Function needs at least two arguments");
auto generate_number = [&](auto range) {
static_assert(
std::is_arithmetic<std::tuple_element_t<0, decltype(range)>>{},
"First argument of std::pair has to be arithmetic!"
);
static_assert(
std::is_arithmetic<std::tuple_element_t<1, decltype(range)>>{},
"Second argument of std::pair has to be arithmetic!"
);
return std::bind(Distribution(range.first, range.second), Generator{});
};
auto genotype = std::make_tuple(generate_number(range)()...);
auto key = std::experimental::apply(function, genotype);
return std::make_pair(key, genotype);
}
#include <cmath>
struct Function {
double operator ()(double x, double y, double z) const {
return std::exp(x + 1.25) * std::pow(y, z) / std::exp(x * y / z);
}
};
#include <iostream>
#include <boost/type_index.hpp>
int main() {
namespace bti = boost::typeindex;
Function f{};
auto x = optimize<100, 200>(
f,
std::make_pair(-21, 37),
std::make_pair(22.5, 88.11),
std::make_pair(-13, 37)
);
std::cout
<< bti::type_id_with_cvr<decltype(x)>().pretty_name() << '\n'
<< x.first << " :: "
<< std::get<0>(x.second) << ", "
<< std::get<1>(x.second) << ", "
<< std::get<2>(x.second) << '\n';
}
Online Demo
Also note that in both places you used decltype(auto), auto can (and for clarity, should) be used instead.
For various reasons I need to use 2 phase construction, furthermore the last phase is deferred and performed by another thread, some context:
...
#define BOOST_PP_LOCAL_MACRO(n) \
template < typename ConnectionType, BOOST_PP_ENUM_PARAMS(n, typename T) > \
boost::shared_ptr< ConnectionType > Connect( BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg) ) \
{ \
boost::shared_ptr< ConnectionType > con( boost::make_shared< ConnectionType >() ); \
boost::mutex::scoped_lock sl( m_AddNetworkJobMutex ); \
m_NetworkJobs.push_back( boost::bind( static_cast< void ( ConnectionType::* )( BOOST_PP_ENUM_PARAMS(n,T) ) >( &ConnectionType::Init ), con, BOOST_PP_ENUM_PARAMS(n, arg) ) ); \
return con; \
}
#define BOOST_PP_LOCAL_LIMITS (1, 5)
#include BOOST_PP_LOCAL_ITERATE()
...
The problem here is that I want to select the best match possible from the overload set for ConnectionType::Init, but the cast is distinct and can't find a perfect match even if some of the arguments are convertible. So the questions becomes: Is it possible to somehow get the type & pointer to the best match from the overload set without actually calling it? Can't use anything which isn't available in C++03.
You can leverage lazy evaluation expression templates.
AFAIK bind expressions are precisely in that family (as are Boost Proto epxressions, Spirit Grammar parse expressions etc.).
Update finally got my act together. However, it only works with callable objects with overloaded operator(). I suppose you can use something like this as glue?
I now show both C++03 and C++11 proofs-of-concept that might help get something of a glue functor built-up around this
The C++03 is near equivalent (see the // TODO in the code)
The C++03 version depends on Boost Typeof and Boost Bind (see Boost Utility doc for result_of for backgrounds on result types of polymorphic function objects)
Both versions live on IdeOne
C++03 (live on https://ideone.com/VHcEC)
Here is a partial port of the C++11 demo (below) into C++03 + Boost:
#include <string>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/typeof/typeof.hpp>
struct overloaded
{
typedef int result_type;
int operator()(const std::string& s) const { return 1; }
int operator()(double d) const { return 2; }
};
struct factory
{
template <typename T> struct result { typedef BOOST_TYPEOF_TPL(boost::bind(overloaded(), T())) type; };
template <typename T>
typename result<T>::type operator()(const T& t) const
{
return boost::bind(overloaded(), t);
}
};
int main()
{
overloaded foo;
// based on local bind expression:
BOOST_AUTO(unresolved, boost::bind(foo, _1));
std::cout << unresolved("3.14") << std::endl; // should print 1
std::cout << unresolved(3.14) << std::endl; // should print 2
// based on a factory function template
factory makefoo;
std::string str("3.14"); // TODO get rid of this explicit instanciation?
std::cout << makefoo(str)() << std::endl; // should print 1
std::cout << makefoo(3.14)() << std::endl; // should print 2
}
C++11 (live on https://ideone.com/JILEA)
As a simple example, this should work alright:
#include <string>
#include <iostream>
#include <functional>
using namespace std::placeholders;
struct overloaded
{
int operator()(const std::string& s) const { return 1; }
int operator()(double d) const { return 2; }
};
template <typename T>
auto makefoo(const T& t) -> decltype(std::bind(overloaded(), t))
{
return std::bind(overloaded(), t);
}
int main()
{
overloaded foo;
// based on local bind expression:
auto unresolved = std::bind(foo, _1);
std::cout << unresolved(3.14) << std::endl; // should print 2
std::cout << unresolved("3.14") << std::endl; // should print 1
// based on a factory function template
std::cout << makefoo(3.14)() << std::endl; // should print 2
std::cout << makefoo("3.14")() << std::endl; // should print 1
}