I have an utility function which takes two values and does something on another object if two values meet a certain criteria.
So, the utility function has to take a member function as a std:function and also sometimes as a free flowing function.
class A
{
public:
void fun(int a) {}
};
template <typename T>
bool ifSet(T a, T b, std::function<void(T)> f )
{
if (a == b) return false;
else return f(b);
}
int main() {
auto p = std::make_shared<A>(new A);
std::cout<< ifSet(10, 10, std::bind(A::fun, p, std::placeholders::_1));
The above code is my dummy implementation, but doesn't work. Can someone suggest me a better code ?
Your
std::function<void(T)> f
return a void and you use it as return for bool ifSet() function
Related
I am trying to create a template class which would in turn generate a wrapper over a function. The class will then return the wrapper as result. I would like to use template to have general class that will work with any function with different signatures, such as:
std::function<void()>task = std::bind(fun1, param1, param2);
std::function<int(int, int)>task = std::bind(fun2, param1, param2);
I would like to have something like this:
template <typename T1, typename T2>
class A {
A (string param1, string param2) {
// The created wrapper here i.e. 'task' will be returned by the class.
function<T1>task = bind(T2, param1, param2);
}
// Return the created wrapper in the constructor.
function<T1> returnWrapper() {
return task;
}
};
The code above is mostly a pseudo code since it cannot be compiled, but gives an idea about what I am looking for. Is there any solution for this? I think there should be more than simply use a template for a function's signature. Any help would be highly appreciated. I also would like to be able to pass arbitrary number of parameters to 'bind' if possible.
I think I solved the problem! I had to define a class which takes two type names inside a template and pass one of them to std::function as function signature after currying and use the second one in the constructor to define the curried function (result function after wrapping) in std::bind. Then everything worked fine! There might be some better solution, but this was the best and more or less clear solution I got. Here is the got snippet of the solution I found! Hope it helps the other with the same issue:
#include <iostream>
#include <functional>
using namespace std;
class A {
private:
template <typename T1, typename T2>
class B {
private:
function<T1>ff;
public:
B(T2 fun) {
ff = bind(fun, 1, placeholders::_1);
}
virtual ~B() {
}
int exec(int x) {
return ff(x);
}
};
static int myFun(int x, int y) {
return x + y;
}
public:
A() {
};
int test() {
B<int(int), int (*)(int, int)> b(&myFun);
return b.exec(10);
}
virtual ~A() {
};
};
int main() {
A a;
// Correct result is '11' since we pass 11 and 1 is in the curried function.
cout << "test result: " << a.test() << endl;
return 0;
}
My C++ is rusty. I'd like MyClass to know nothing about Foo and have a callback to run a function in foo. I don't know how to define callback_pair or how to call SetCallback
class MyClass{
tuple<cb, ptr> callback_pair
int run() {
auto that=callback_pair<1>();
auto cb = callback_pair<0>();
int a=1, b=2, c=3;
auto result = cb(that, a, b, c); //this calls foo.the_function
return result;
}
void SetCallback(tuple<cb, ptr> cb) { callback_pair=cb; )
};
class Foo {
int d;
int the_func(int a, b, c) {
return a+b+c+d
}
}
//myclass.SetCallback(what_do_I_write_here)
Well, MyClass must know something about Foo, namely the signature of whatever method you plan on using as a callback; otherwise, how would it know what to pass in as parameters, or what type to expect to get as output? If the callback signature is known and fixed, for instance int(int,int,int) as you have above, you could use a construction like this:
class MyClass {
std::function<int(int,int,int)> callback;
public:
int run() {
return callback(1,2,3); // or whatever
}
template <typename Class>
void SetCallback (Class& o, int (Class::*m) (int,int,int)) {
callback = [&o,m] (int a, int b, int c) { return (o.*m)(a,b,c); };
}
template <typename Class>
void SetCallback (Class const& o, int (Class::*m) (int,int,int) const) {
callback = [&o,m] (int a, int b, int c) { return (o.*m)(a,b,c); };
}
};
The above implementation of MyClass works as follows: callback is a function object, initially undefined, which takes three ints and returns an int. SetCallback takes two parameters: An object o on which the callback should be performed and a method m on that object which conforms to the signature of callback. It doesn't care what the type of o is; thanks to type-erasure, MyClass never needs to know what it's actually calling.
Take special notice of the two versions of SetCallback -- one each for const and non-const objects. In reality, you should be writing overloads for volatile and const volatile as well, but those are comparatively much rarer than const. In the future, once exception specifications and transactions become part of the type system, we will also have to care about noexcept and synchronization, and the resulting combinatoric explosion of types will be difficult to deal with effectively without some very clever language support. But this example shows you how that sort of code would be written, and it's probably good enough for your purposes.
The implementation looks ugly, but it actually provides a very clean interface; given Foo as you've written above, you would use MyClass's callback functionality like this:
MyClass test;
Foo foo;
foo.d = 4;
test.SetCallback (foo, &Foo::the_func);
int result = test.run(); // result = 10
The above code will work with any type that has a method with the signature int(int,int,int). Note that you must call SetCallback before you call run, or else you'll get a std::bad_function_call exception because the callback hasn't been defined yet.
Suppose I wanted to implement std::find_if from <algorithm>. Here is one possible way I tried that works.
template <class In, class F>
In find_if(In b, In e, F f)
{
while (b != e)
{
if (f(*b))
return b;
b++;
}
return e;
}
Here it seems that the user needs to know to pass an argument that returns a bool value. Part of my question regards if there is any way to restrict what is passed to F f using this technique.
Another way to implement this would involve the use of function pointers:
template <bool (*F)(int), class In>
In find_if(In b, In e)
{
while (b != e)
{
if (F(*b))
return b;
b++;
}
return e;
}
Are there any differences between these two methods (other than the way they must be called; i.e the first way is called with find_if(arg1,arg2,f) and the second way is called withfind_if<f>(arg1,arg2).
If there are differences, could you please delineate and explain them to me?
Passing a function pointer is more restrictive than passing a type where we apply (*b) on it.
In the case of the class, you may pass
functor class (which may have state) as:
struct HasName {
explicit HasName(const std::string& name) : name(name) {}
template <typename T>
bool operator () (const T& t) const { return t.get_name() == name; }
std::string name;
};
or any function pointer where f(*b) is correct (so f can take float whereas *b is an int, for example).
or lambda (C++11).
Working on a simple example for template functions. The code compiles and works as expected. But my question is why "static" is required in both "Cmp" and "Lit"? Otherwise, it will not compile?
Thanks a lot!
template<class T> class Cmp{
public:
static int work(T a, T b) {
std::cout << "Cmp\n";
return 0;
}
};
template<class T> class Lit{
public:
static int work(T a, T b){
std::cout << "Lit\n" ;
return 0;
}
};
template<class T, class C>
int compare(const T &a, const T &b){
return C::work(a, b);
}
void test9(){
compare<double, Cmp<double> >( 10.1, 20.2);
compare<char, Lit<char> >('a','b');
}
C::work(a, b) names a static member function work() of class C.
The reason that static is required here is that in the compare template function, you have this line:
return C::work(a, b);
The syntax C::work(a, b) here means "call the function work nested inside the class C. Normally, this would try to call a member function without providing a receiver object. That is, typically the way you'd call a function work would be by writing
C myCObject;
myCObject.work(a, b);
In this case, though, we don't want to be calling a member function. Instead, we want the function work to be similar to a regular function in that we can call it at any time without having it act relative to some other object. Consequently, we mark those functions static so that they can be called like regular functions.
Hope this helps!
If the function pointer embedded in a boost::bind return object is NULL/nullptr/0, I need to take action other than calling it. How can I determine if the object contains a null function pointer?
Addenda
I don't believe I can use and compare boost::functions as the boost::bind return object is used with varying call signatures in a template function.
Simplified example:
template <typename BRO>
Retval do_stuff(BRO func, enum Fallback fallback)
{
if (func == NULL)
{
return do_fallback(fallback);
}
else
{
return use_retval(func());
}
}
do_stuff(boost::bind(FuncPtrThatMightBeNull, var1, var2), fallback);
Solution
Since the arity of the function in the callee does not change, I can "cast" the bind return object into a boost::function and call .empty()
Retval do_stuff(boost::function<Retval()> func, enum Fallback fallback)
{
if (func.empty())
return do_fallback(fallback);
else
return use_retval(func());
}
You can either bind to a dummy function:
void dummy() { /* has differing behaviour */ }
// ...
boost::bind(&dummy)();
... or, assuming you're using Boost.Bind together with Boost.Function, return a default constructed function object and check for empty() before calling it:
typedef boost::function<void (void)> F;
F create() { return F(); }
void use() {
F f = create();
if(f.empty()) {
/* ... */
}
}
Regarding the update:
I still don't see what the problem with binding to a different function like the following would be:
template <typename BRO>
Retval do_stuff(BRO func)
{
return func();
}
if(funcPtr) {
do_stuff(boost::bind(&use_retval, boost::bind(funcPtr, a, b)));
} else {
do_stuff(boost::bind(&do_fallback, fallback));
}
If you'd want to move that handling out of the calling code, you could emulate variadic template function to support variable arities:
template<class R, class T1>
boost::function<R (T1)>
bind_wrap(R (*fnPtr)(), T1& t1, Fallback fallback) {
if(fnPtr) return boost::bind(&use_retval, boost::bind(funcPtr, t1));
else return boost::bind(&do_fallback, fallback);
}
template<class R, class T1, class T2>
boost::function<R (T1, T2)>
bind_wrap(R (*fnPtr)(T1, T2), T1& t1, T2& t2, Fallback fallback) {
if(fnPtr) return boost::bind(&use_retval, boost::bind(funcPtr, t1, t2));
else return boost::bind(&do_fallback, fallback);
}
// ... etc. for all needed arities
do_stuff(bind_wrap(funcPtr, var1, var2, fallback));
... or you use the approach above to generate boost::function<> objects or your own wrappers and check for functor.empty() or similar in do_stuff().
I'd create a wrapper object to do this. Something like the following
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
int aFunction(int i, int j)
{
std::cout<<"In a Function"<<std::endl;
return i+j;
}
struct DefaultingFromFnPtr : public boost::function< int(int,int) >
{
explicit DefaultingFromFnPtr( int(*fn)(int,int) ) : fn_(fn) {}
int operator()(int i, int j) const
{
if (fn_!=NULL) return fn_(i, j);
return 7;
}
int(*fn_)(int,int);
};
template<typename T>
void do_stuff( T t )
{
std::cout<<"RETURNED "<<t()<<std::endl;
}
int main( int argv, const char** argc)
{
int(*mightBeNullFnPtr)(int,int) = NULL;
if( argv>1)
{
mightBeNullFnPtr = & aFunction;
}
int var1 = 10;
int var2 = 20;
do_stuff( boost::bind( DefaultingFromFnPtr( mightBeNullFnPtr ), var1, var2 ) );
}
Compile this and run it with no arguments and it sets mightBeNullFnPtr to NULL and calls do_stuff with a wrapper class, and so prints out 7. Run it with an argument and it will set mightByNullFnPtr to aFunction and calls do_stuff with that, printing out 30.
If you want more genericity you will need to template the DefaultingFromFnPtr wrapper class, but that should be pretty easy to do.
I'm pretty sure calling boost::bind with a null pointer (= the creation of the bind object) should be considered undefined behavior, even if the crash only happens when calling it.
You're going to have to hack boost.
boost::bind returns unspecified-n-n. The only thing valid to do with these classes is operator(). The only other thing you know is that they are copy constructable, and have a typedef for result_type (which, by the way, means you don't need a template for result type).
You want something else - so you'll need to find the definition of unspecified-n-n in boost (there maybe several), hack them to have a is_null() member function which checks for the conditions you want, then call that as your test.
This is, of course, assuming you are certain you'll always get a boost::bind'ed object in your template function. If someone tries passing in a regular function pointer, it won't compile. Working around this will require some template magic.