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
Related
I'm working with a legacy codebase which uses a bunch of callbacks to member functions. As part of a refactoring effort, I'm attempting to wrap these callback calls.
My current implementation is attempting to use a variadic template function to replace/wrap the bind call.
template< typename F, typename T, typename... Args >
auto
my_bind(F fxn, T * obj, Args&&... args)
-> decltype( boost::bind( fxn, obj, std::forward<Args>(args)... ) )
{
return boost::bind( fxn, obj, std::forward<Args>(args)... );
}
(The actual implementation will add wrapper classes around the fxn & obj objects, but I removed that to give a minimal example which still shows the issue.)
This mostly works, but fails where the fxn object is an overloaded member function. In this situation, I'm getting "couldn't deduce template parameter ‘F’"/"couldn't infer template argument 'F'" (GCC/Clang) errors. This makes a bit of sense, as there's multiple possible functions with different parameter types which could be used.
What's confounding me is that boost::bind is not having issues with the member resolution -- in the original code without the wrapper, I don't see any errors and the binding goes well. Example:
#include <iostream>
#include <boost/bind.hpp> // Boost 1.53
template< typename F, typename T, typename... Args >
auto
my_bind(F fxn, T * obj, Args&&... args)
-> decltype( boost::bind( fxn, obj, std::forward<Args>(args)... ) )
{
return boost::bind( fxn, obj, std::forward<Args>(args)... );
}
class Klass {
public:
void foo( int i ) {
std::cout << "One param: " << i << "\n";
}
void foo( int i, int j ) {
std::cout << "Two param: " << i << " " << j << "\n";
}
void bar( int const & i ) const {
std::cout << "Bar One param: " << i << "\n";
}
int bar( float i, int j ) {
std::cout << "Bar Two param: " << i << " " << j << "\n";
return j;
}
};
int main() {
Klass k;
auto f1 = boost::bind( &Klass::foo, &k, 1 );
f1(); // prints "One param: 1"
auto f2 = boost::bind( &Klass::foo, &k, 1, 2 );
f2(); // prints "Two param: 1 2"
//auto f1a = my_bind( &Klass::foo, &k, 1 ); // Compiler error: couldn't deduce template parameter ‘F’
//auto f2a = my_bind( &Klass::foo, &k, 1, 2 ); // Compiler error: couldn't deduce template parameter ‘F’
double a = 1.1;
int b = 3;
//auto b1 = my_bind( &Klass::bar, &k, b ); // Should also work with const functions and const parameters
//auto b2 = my_bind( &Klass::bar, &k, a, 2 ); // As well as non-void return types and parameter conversions
// As well as any other member function which the underlying sub-function (here boost::bind) can take.
return 0;
}
My main question: Given a function (such as, but not necessarily limited to boost::bind) which is able to appropriately distinguish between different versions of an overloaded member function, is there a way to create a templated wrapper function which can "perfectly forward" the template type from that functions parameter -- that is, is there a way to permit the compiler to make the F type deduction based on the (working) type deduction of the sub-function (e.g. boost::bind)?
(I did try replacing the my_bind template function with a variadic preprocessor macro. This fixes the immediate problem, but results in issues later, when I attempt to wrap the fxn object in a templated type. -- I get similar "cannot resolve overloaded function" errors.)
I'm targeting C++11, if that makes a difference.
you may try to force the type of the member function expected like:
#include <iostream>
#include <boost/bind.hpp> // Boost 1.53
template<typename T, typename... Args>
auto
my_bind(void (T::*fxn)(Args...), T * obj, Args&&... args)
-> decltype( boost::bind( fxn, obj, std::forward<Args>(args)... ) )
{
return boost::bind( fxn, obj, std::forward<Args>(args)... );
}
class Klass {
public:
void foo( int i ) {
std::cout << "One param: " << i << "\n";
}
void foo( int i, int j ) {
std::cout << "Two param: " << i << " " << j << "\n";
}
};
int main() {
Klass k;
auto f1a = my_bind( &Klass::foo, &k, 2 );
f1a(); // prints One param: 2
auto f2a = my_bind( &Klass::foo, &k, 2, 3 );
f2a(); // prints Two param: 2 3
return 0;
}
I am currently trying to teach myself variadic templates. However I am having trouble understanding anything past a simple adding template.
Currently I would want a template that would do the following:
Take any number of types
Takes parameters that requires the user to enter them in the following format:
T value, string descriptor
It then goes through each variable one by one, printing the descriptor before reading the variable
For example the output should look like this:
x (int) //this is the descriptor
//here something is being read into the variable x
y (int) //this is another descriptor
//something else is being read into y
.
.
.
Since its always the same operation, this should be possible. However my best try looked like this
template<typename t,typename... Args>
void generic_reader(t first,string desc,Args... args)
{
cout<<desc<<endl;
cin>>first;
generic_reader(args);
}
Obviously this doesnt work. However I cant think of another way of doing this. Again I have only started to work with variadic templates.
Can someone show me a solution with a detailed explanation?
Here's one way, using recursion.
#include <iostream>
// provide a terminating case
void generic_read()
{
}
// provide the general case which picks off the first 2 arguments
// and forwards the rest to another version of itself.
template<typename T, typename Printable, typename...Rest>
void generic_read(T& value ,Printable&& desc,Rest&&...rest)
{
std::cout << desc << std::endl;
std::cin >> value;
generic_read(std::forward<Rest>(rest)...);
}
// test
int main()
{
int x;
double y;
generic_read(x, "an integer:", y, "a double");
}
You're basically there -- you're just missing a base case. Also, you're missing the ... on your recursive call to generic_reader; it should be generic_reader(args...).
Here's some working code that does what you're trying to do:
#include <string>
#include <iostream>
void generic_reader()
{
std::cout << "no more stuff!" << std::endl;
}
template <typename T, typename... Args>
void generic_reader(T& first, const std::string& desc, Args&... args)
{
std::cout << desc << std::endl;
std::cin >> first;
std::cin.ignore(100, '\n');
generic_reader(args...);
}
int main()
{
int x, y, z;
generic_reader(x, "x", y, "y", z, "z");
std::cout << "x: " << x << " y: " << y << " z: " << z << std::endl;
return 0;
}
`
Walking through the code: your approach was correct, but there's no base case when you run out of arguments. On the second to last call, the remaining arguments are (z, "z"), which substitutes into the template successfully. But after that, there is a final call to generic_reader(), with no remaining arguments. You need to provide a candidate that can accept the final (empty) argument list.
One final note -- you'll notice that I passed in first by reference, so I could write to the original variables. If you do this, make sure that the remaining Args... is passed by reference as well! Otherwise, recursive calls will pass the remaining args by value, and calls after the first one will no longer reference the original variables.
It seems to me that you're using a sequence of std::pairs where the first type is fixed, std::string, and the second one is a variable type.
So you can write your function as
template <typename ... Args>
void generic_reader (std::pair<std::string, Args> & ... ps)
{ /* do something */}
and call it as
auto a = std::make_pair<std::string>("a", short(0));
auto b = std::make_pair<std::string>("b", 1);
auto c = std::make_pair<std::string>("c", 2L);
auto d = std::make_pair<std::string>("d", 3LL);
generic_reader(a, b, c, d);
Unfortunately I don't know (before c++17) how to use ps... in the body of the function so, in C++11 and in C++17, the best I can think is a solution based on recursion (as your original, with the recursion call corrected in generic_reader(args...);)
Starting from C++17 it's available a new (and more powerful) mode of use variadic arguments (look for "fold expression") and your function ca be simply written as
template <typename ... Args>
void generic_reader (std::pair<std::string, Args> & ... ps)
{ ( (std::cout << ps.first << std::endl, std::cin >> ps.second), ... ) ; }
The following is a full working C++17 example
#include <utility>
#include <iostream>
template <typename ... Args>
void generic_reader (std::pair<std::string, Args> & ... ps)
{ ( (std::cout << ps.first << std::endl, std::cin >> ps.second), ... ) ; }
template <typename ... Args>
void variadic_printer (Args & ... as)
{ ( (std::cout << as.first << ", " << as.second << std::endl), ... ) ; }
int main ()
{
auto a = std::make_pair<std::string>("a", short(0));
auto b = std::make_pair<std::string>("b", 1);
auto c = std::make_pair<std::string>("c", 2L);
auto d = std::make_pair<std::string>("d", 3LL);
generic_reader(a, b, c, d);
variadic_printer(a, b, c, d);
}
If you prefer not to use recursion you can always use this (c++14, but there exist implementations of index_sequence for c++11):
#include <utility>
#include <iostream>
#include <tuple>
template <class Tuple, std::size_t... Is>
void generic_reader_impl(std::index_sequence<Is...>, Tuple&& tuple) {
std::size_t dummy[] = { 0ul,
(static_cast<void>(std::cout << std::get<2ul*Is + 1ul>(tuple) << std::endl),
static_cast<void>(std::cin >> std::get<2ul*Is>(tuple)),
Is)...
};
static_cast<void>(dummy);
}
template <class... Args>
void generic_reader(Args&&... args) {
generic_reader_impl(std::make_index_sequence<sizeof...(Args) / 2>{}, std::forward_as_tuple(std::forward<Args>(args)...));
}
int main() {
int x;
double y;
generic_reader(x, "an integer:", y, "a double");
std::cout << x << std::endl;
std::cout << y << std::endl;
}
Output:
1
1.2
[live demo]
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.
std::bind is sometimes described as "partial application". Any reasons why when all parameters of a function are bound, the function itself isn't applied?
For example, the following code prints nothing.
#include <functional>
#include <iostream>
using namespace std;
using namespace std::placeholders;
void f(int a,string b) {cout << a << b << endl;};
int main() {
bind(bind(f,1,_1),"Hi!");
return 0;
}
Is there a way to write a bind variant that can apply the function when all parameters are fixed?
--Update--
I understand from the responses now that std::bind is not exactly partial application. So, on the second part of the question, how can I write something like std::bind but does partial application.
I know bind(bind(f,1,_1),"Hi!")() will call the final 0-ary function and return the result value (printing 1Hi in the example). Is it possible to do template programming to call the function call operator () in the terminal case of bind?
In other words, is it possible to write a function bind1:
template< class R, class F, class... Args >
bind1( F f, Args... args )
, such that when std::is_placeholder<T>::value == 0 for each member of args,
bind1() can, in addition to what std::bind() does, call the operator()?
A function with no arguments is just a value in Haskell. You don't call it, you just use it. Since there are no side effects, there is no observable difference.
In OCaml there are simply no parameter-less functions, to get something like that you need to add a dummy unit argument.
Not so in C++. C++, unlike Haskell and OCaml, maintains clear difference between f and f(). bind gives you the former because you can always turn it into the latter by adding (). You can write your own wrapper for bind that does just that quite easily. Going the other way around would be a tad more difficult.
Here's a possible implementation of such wrapper:
#include <functional>
#include <utility>
#include <iostream>
template <typename T>
struct is_noargs_callable {
private:
typedef char(&yes)[1];
typedef char(&no)[2];
template<typename U>
static yes test(decltype((std::declval<U>())())*);
template<typename>
static no test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
template <typename T>
struct is_noargs_callable<T()> {
static const bool value = true;
};
template <typename T>
struct is_noargs_callable<T(...)> {
static const bool value = true;
};
template <typename T>
auto call_me_if_you_can(T t) -> typename std::enable_if<is_noargs_callable<T>::value, decltype(t())>::type
{
return t();
}
template <typename T>
auto call_me_if_you_can(T t) -> typename std::enable_if<!is_noargs_callable<T>::value, T>::type
{
return t;
}
template <typename... Args>
auto apply(Args&&... args) -> decltype(call_me_if_you_can(std::bind(args...))) {
return call_me_if_you_can(std::bind(args...));
}
// testing
void foo(int a, int b, int c) { std::cout << "foo(" << a << "," << b << "," << c << ")"; }
int main ()
{
using namespace std::placeholders;
std::cout << "zero : " ; apply(foo, _1, _2, _3); std::cout << " : " ; apply(foo, _1, _2, _3)(1,2,3); std::cout << std::endl;
std::cout << "one : " ; apply(foo, 1, _1, _2); std::cout << " : " ; apply(foo, 1, _1, _2)(2,3); std::cout << std::endl;
std::cout << "two : " ; apply(foo, 1, 2, _1); std::cout << " : " ; apply(foo, 1, 2, _1)(3); std::cout << std::endl;
std::cout << "three: " ; apply(foo, 1, 2, 3); std::cout << " : "; /* nothing to test here */ std::cout << std::endl;
}
However, killing the difference between f and f() just in this one place does not IMHO contribute to the overall consistency of C++ programming. If you don't like the distinction, kill it everywhere (or just use you a Haskell for great good).
No sources for this, just my opinion.
The reason that wasn't done is because there is no reason to do it. If you know all of the input to the function, just call it.
And if you were doing something with templates that resulted in this, you would need to write all of the code consistently anyway. A special case here would only require a special case somewhere else.
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);
}