I want run to call c.drive():
#include <functional>
using namespace std;
struct Car {
void drive() { }
};
template <typename Function>
void run(Function f) {
f();
}
int main() {
Car c;
run(bind1st(mem_fun(&Car::drive), &c));
return 0;
}
This does not compile and the error messages does not help me:
at f():
no match for call to ‘(std::binder1st<std::mem_fun_t<void, Car> >) ()’
at the call to run:
no type named ‘first_argument_type’ in ‘class std::mem_fun_t<void, Car>’
no type named ‘second_argument_type’ in ‘class std::mem_fun_t<void, Car>’
No boost please.
Update: even though the problem is solved, I would be very happy to see TR1/C++0x solutions!
The Boost/TR1/C++0x solution is quite straightforward:
run(std::bind(&Car::drive, &c));
bind1st makes a unary function out of a binary function and a value. You are trying to make a function that takes no parameters out of a unary function and there isn't anything to support this in standard C++03.
You will have to do something like this.
template<class X, void (X::*p)()>
class MyFunctor
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()() const { (_x.*p)(); }
};
template <typename Function>
void run(Function f) {
f();
}
int main() {
Car c;
run(MyFunctor<Car, &Car::drive>(c));
return 0;
}
The C++0x solution using lambdas - http://www.ideone.com/jz5B1 :
struct Car {
void drive() { }
};
template <typename Function>
void run(Function f) {
f();
}
int main() {
Car c;
run( [&c](){ c.drive(); } );
return 0;
}
Related
I have a bunch of very similar functions:
void foo1(Obj o) {
bar(o.a);
}
void foo2(Obj2 o) {
bar(o.b);
}
void foo3(Obj3 o) {
bar(o.c);
}
How can I reduce the duplicating of code? Can I do something like:
template<typename T, pointerToMember>
void foo(T o) {
bar(o.pointerToMember);
}
And then create all functions like:
foo<Obj, Obj.x>;
...
?
Yes it is possible to have a pointer to member as template parameter:
#include <string>
struct Obj {
int a,b,c;
};
void bar(int x){}
template<typename T, int (T::*pointerToMember)>
void foo(T o) {
bar(o.*pointerToMember);
}
int main() {
Obj x;
foo<Obj,&Obj::a>(x);
}
However, there are different ways that would make the call less verbose. You could pass the member pointer as parameter to be able to deduce it, that would allow to call it as
foo(x,&Obj::a);
Last not least, you could call bar directly
bar(x.a);
Suppose that a class has a member function which should accept either a double(double) function or a class instance with a "MyStructFunc" public member function as an argument:
#include<functional>
#include <type_traits>
struct Caller
{
// (1.)
double call(std::function<double(double)> func) { return func(1); }
// (2.)
template<typename T>
double call(const T& S) { return S.MyStructFunc(2); }
};
So, for example, we can pass
double myFunc(double x) { return x * x * x; }
or
struct myStruct
{
double MyStructFunc(double x) const { return x * x; }
};
like this:
int main()
{
Caller c;
myStruct ms;
c.call(myFunc);
c.call(ms);
}
Unfortunately, I get an error. Could you please help me make it work? Thank you for your help!
function pointer is not a std::function, so your template method is a better match.
You might use SFINAE to restrict your template method:
// (2.)
template<typename T>
auto call(const T& S) -> decltype(S.MyStructFunc(2)) { return S.MyStructFunc(2); }
Demo
Can we chose which function template overload should be used in this case?
struct X { };
struct A { A(X){} };
struct B { B(X){} };
template<class T>
void fun(T, A) { }
template<class T>
void fun(T, B) { }
int main() {
/* explicitly choose overload */ fun(1, X());
}
Error:
error: call of overloaded 'fun(int, X)' is ambiguous
/* explicitly choose overload */ fun(1, X());
^
candidate: void fun(T, A) [with T = int]
void fun(T, A) { }
^~~
candidate: void fun(T, B) [with T = int]
void fun(T, B) { }
^~~
For normal function it looks like this:
void fun(A){}
void fun(B){}
int main() {
((void(*)(A))(fun))(X());
}
Is it possible?
Improving your example, you can try with
((void(*)(int, A))(fun))(1, X());
If you choose not to explicitly specify the first parameter type but still want to specify the second you could go along with lambda dedicated for casting purpose (c++14 solution):
struct X { };
struct A { A(X){} };
struct B { B(X){} };
template<class T>
void fun(T, A) { }
template<class T>
void fun(T, B) { }
int main() {
[](auto v, auto x){ static_cast<void(*)(decltype(v), A)>(fun)(v, x); }(1, X());
}
[live demo]
A low-tech solution to this problem would be to add one extra level of indirection. Add a function like funA, whose sole purpose is to give an explicit name to the first version of fun:
struct X { };
struct A { A(X){} };
struct B { B(X){} };
template<class T>
void fun(T, A) { }
template<class T>
void fun(T, B) { }
template <class T>
void funA(T t, A a) { fun(t, a); }
int main() {
/* explicitly choose overload */ funA(1, X());
}
However, I wonder why you cannot just change the argument to A(X()). You will have to change the calling code anyway, so what's the problem?
Some code I have no control over has a number of overloaded functions which accepts different types
i.e.
setValue(int)
setValue(std::string)
setValue(bool)
And I have a template function which would idealy take any one of these types and pass it on to the correct setValue function.
template <class T>
do_something(T value) {
...
setValue(value);
But I get this error
error: call to member function 'SetValue' is ambiguous
Is there anything I can do to work around this problem without copy and pasting my code for each type like the writers of setValue have?
by defining you own SetValue with exact match and forwarding to the correct overload.
void setValue(int i) { setValue(static_cast<double>(i)) }
or (if you have a lot of "setValue" functions with same type) you may help the compiler to choose which overload to use like this:
void setValue(char a);
void setValue(double a);
template <typename T>
struct TypeToUseFor
{
typedef T type;
};
template <>
struct TypeToUseFor<int>
{
typedef double type;
};
template <class T>
void func(T value)
{
setValue(static_cast<typename TypeToUseFor<T>::type>(value));
// setValue(value);
}
int main() {
func(0); // int -> ?
func('0'); // exact match
func(0.0); // exect match
func(0.f); // float -> double
return 0;
}
I have no problems with:
void setValue(int a)
{
}
void setValue(std::string a)
{
}
void setValue(bool a)
{
}
template <class T>
void func(T value)
{
setValue(value);
}
int main()
{
func(5);
}
Here is my run: http://codepad.org/1wq8qd7l
I need a function wrapper for std::bind that will be called before the function it's wrapper, passing the arguments along to the wrapped functions.
std::function<void (int)> foo = postbind<int>(service, handle);
I've so far got down to that
std::function<void (int)> foo = postbind(service, handle);
How can I remove that template parameter? It seems to come down to the type deduction from the object generation function (postbind) not being intelligent enough.
#include <functional>
template<typename T>
void foo(std::function<void (T)> func)
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
Says error: no matching function for call to 'foo(void (&)(int))'
Yet, the code sample:
template<typename T>
void foo(T t)
{
}
int main()
{
foo(99);
return 0;
}
This works. Any ideas how to make this work? I need to be able to pass std::bind to it and have the result cast successfully to std::function.
How can I remove the template parameters? Thanks.
Q. What is service and this class meant to do?
A. Encapsulate a function wrapper that boost::asio::io_service->posts out of the current thread.
Full sourcecode:
#include <iostream>
#include <functional>
#include <memory>
class io_service
{
};
typedef std::shared_ptr<io_service> service_ptr;
template <typename Arg1>
class postbind_impl_1
{
public:
typedef std::function<void (Arg1)> function;
postbind_impl_1(service_ptr service, function memfunc)
: service_(service), memfunc_(memfunc)
{
}
void operator()(Arg1 arg1)
{
// do stuff using io_service
memfunc_(arg1);
}
private:
service_ptr service_;
function memfunc_;
};
template <typename Arg1>
postbind_impl_1<Arg1> postbind(service_ptr service,
typename postbind_impl_1<Arg1>::function handle)
{
return postbind_impl_1<Arg1>(service, handle);
}
// ----------------
void handle(int x)
{
std::cout << x << "\n";
}
int main()
{
service_ptr service;
std::function<void (int)> foo = postbind(service, handle);
foo(110);
return 0;
}
AFAICT argument types of a bind expression are not deducible, so what you want is pretty much impossible.
How do you expect the compiler to know to use std::function? In this code:
#include <functional>
template<typename T>
void foo(T func)
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
T is NOT std::function<void (int)>. It's void (&)(int) (like the error message said), a reference to a function, not a functor object.
Deduction of the argument type of the passed function should work, try:
#include <functional>
template<typename T>
std::function<void (T)> foo(void (*func)(T))
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
Demo: http://ideone.com/NJCMS
If you need to extract argument types from either std::function or a plain function pointer, you'll need a helper structure:
template<typename>
struct getarg {};
template<typename TArg>
struct getarg<std::function<void (TArg)>> { typedef TArg type; };
template<typename TArg>
struct getarg<void (*)(TArg)> { typedef TArg type; };
template<typename TArg>
struct getarg<void (&)(TArg)> { typedef TArg type; };
template<typename T>
std::function<void (typename getarg<T>::type)> foo(T func)
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
Demo: http://ideone.com/jIzl7
With C++0x, you can also match anything that implicitly converts to std::function, including return values from std::bind and lambdas: http://ideone.com/6pbCC
I'm not entirely sure what you're trying to achieve, but here's a naive wrapper that stores a list of actions:
template <typename R, typename A>
struct wrap
{
typedef std::function<R(A)> func;
wrap(func f_) : f(f_) { }
void prebind(func g) { prebound.push_back(g); }
R operator()(A arg)
{
for (auto it = prebound.cbegin(); it != prebound.cend(); ++it)
{
func g = *it;
g(arg);
}
f(arg);
}
private:
std::vector<func> prebound;
func f;
};
wrap<void, int> make_wrap(std::function<void(int)> f)
{
return wrap<void, int>(f);
}
Usage:
auto foowrap = make_wrap(foo);
foowrap.prebind(std::function<void(int)>(action1);
foowrap.prebind(std::function<void(int)>(action2);
foowrap(12); // calls action1(12), action2(12), foo(12)
To all the naysayers who said this wasn't possible :)
/*
* Defines a function decorator ala Python
*
* void foo(int x, int y);
* function<void ()> wrapper(function<void (int)> f);
*
* auto f = decorator(wrapper, bind(foo, 110, _1));
* f();
*/
#include <functional>
template <typename Wrapper, typename Functor>
struct decorator_dispatch
{
Wrapper wrapper;
Functor functor;
template <typename... Args>
auto operator()(Args&&... args)
-> decltype(wrapper(functor)(std::forward<Args>(args)...))
{
return wrapper(functor)(std::forward<Args>(args)...);
}
};
template <typename Wrapper, typename Functor>
decorator_dispatch<
Wrapper,
typename std::decay<Functor>::type
>
decorator(Wrapper&& wrapper, Functor&& functor)
{
return {wrapper, functor};
}