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.
Related
I'm wrapping a C function in a C++ function. The C function accepts a function pointer (with state). I want to allow a C++ callable. A code sample says a thousand words so...
//======================================================
// All this stuff is defined in C somewhere else
// C string type
typedef struct FooString { const char* str; size_t length; } FooString;
// C function pointer type
// This keeps getting called until it returns something with length == 0
typedef FooString (*CFunctionPointer)(void* state);
// Function being wrapped
void quux(CFunctionPointer fPtr, void* state)
{
FooString str;
while(1)
{
str = fPtr(state);
if(str.length == 0)
break;
else
{
// do something
}
}
}
//======================================================
// Here's what I need help with
template<typename IteratorFunctor>
void quuxWrapper(IteratorFunctor& iterator) const
{
// type that the functor returns, and related types
using TIn = decltype(iterator());
using TNoRef = typename std::remove_reference<TIn>::type;
using TYesRef = typename std::add_lvalue_reference<TNoRef>::type;
using TStored = typename std::conditional<std::is_reference<TIn>::value, std::reference_wrapper<TNoRef>, TIn>::type;
// store this on the stack in this function, and pass a pointer to it into the C library
// the C callback will pass back the pointer, and we can get at all this stuff from within the lambda
struct CallbackContext
{
bool isFirst; // is this the first iteration?
IteratorFunctor& iterator; // reference to the iterator in a place we can get to from inside the C function pointer callback
TStored current; // current value (either an actual value stored on the stack, or a reference wrapper)
};
CFunctionPointer cFunctionPtr = [](void* pContext) -> FooString
{
CallbackContext& context = *((CallbackContext*) pContext);
// on the first iteration, we return the value already fetched (need to do this to support things that
// aren't DefaultConstructable). On subsequent iterations, call the functor again.
if(context.isFirst)
context.isFirst = false;
else
context.current = context.iterator();
// this is needed for supporting both references as reference_wrappers and value types. we take a reference
// which forces reference_wrapper to call its conversion operator and is basically a no-op for value types
// (something like context.current.length would fail for reference_wrapper)
TYesRef current = context.current;
// stop iteration if functor returns anything with length 0
if(current.length() == 0)
return FooString{nullptr, 0};
else
return FooString{current.data(), current.length()};
};
// create the context and make the first call to the iterator
CallbackContext context{true, iterator, iterator()};
// and then call the C function
quux(cFunctionPtr, &context);
}
This supports returning a std::string or std::string& from the functor. It also allows users to return their own type, as long as that type has length() and data() methods. It doesn't allow the functor to return a std::string*, though, which is what I'd like to support.
Is there a good way to do this using C++11 features (and no dependencies or weird compiler hacks, since this is part of the public API)?
template<class F, class R=std::result_of_t<F&()>>
struct c_callback {
F state;
void* get_pvoid() { return std::addressof(state); }
using C_sig = R(*)(void*);
static C_sig get_pfunc() {
return [](void* pvoid)->R {
F* pstate = static_cast<F*>(pvoid);
return static_cast<R>( (*state)() );
};
}
};
this wraps a lambda or other C++ invokable into a function pointer and pvoid. It does nothing else. The return value is either deduced or passed.
Your second problem is wanting to adapt return values.
template<class T>
FooString to_foostring_f( T& t ) {
return {t.data(), t.length()};
}
template<class T>
FooString to_foostring_f( T* t ) {
if (!t) return {0,0};
return to_foostring_f(*t);
}
auto to_foostring = [](auto&& t)->FooString {
return to_foostring_f( decltype(t)(t) );
};
to_foostring is a function object that takes something, and returns a FooString. It does this by calling to_foostring_f. You can enhance it with ADL.
Finally write compose(First, Second) which returns Second(First(Args...)).
Stitch these together and it should work.
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
I have a number of function pointers bound with their respective class objects:
ExampleClass EO;
std::function<void()> Example=std::bind(&ExampleClass::ExampleFunction, &EO);
However, I'd like to 'unbind' these at a later point, specifically to identify the specific class which each of the 'std::function's relate to.
auto Unbind(std::function<void()> &Example)->void
{
//Find which object &Example is bound with (in this case EO/ExampleClass)
}
What's the best way of doing this?
std::function performs type erasure. As per the name, it erases the real underlying types from the interface.
There is no way back from there.
If you want to preserve the type of the target object, then std::mem_fn might be what you want:
http://en.cppreference.com/w/cpp/utility/functional/mem_fn
You cannot do it with a function object.
A possibility is to construct a wrapper in which to store the reference to the method and the object.
Something like this:
template<typename T, typename Fn>
struct MemberFunctionPointer {
MemberFunctionPointer(T* ref, Fn fn) : m_ref(ref),
m_method(fn) { }
template<typename... Args>
auto operator()(Args&&... args) {
return (m_ref->*m_method)(std::forward<Args...>(args)...);
}
T* m_ref = nullptr; // a reference (pointer) to the object instance
Fn m_method = nullptr; // a reference to the function method
};
Note: this is just a scratch. You should add a more sophisticated interface. Moreover a helper function in order to create a MemberFunctionPointer object could be useful as well.
You can pass that kind of object instead of a simply function.
struct Foo {
void bar() {
// something
}
};
int main(int argc, char *argv[]) {
Foo f;
MemberFunctionPointer<Foo, decltype(&Foo::bar)> method(&f, &Foo::bar);
method(); // call the method on the object f.
assert(&f == method.get_obj_reference());
return 0;
}
after yesterday's rip-roaring thread at How to implement a simple event queue? , I decided to finally make the big leap to c++11. Just before c++14 comes out probably...
Anyway, it occured to me that variadic functions are the perfect way forward in this enjoyable endeavour. They probably aren't really, but anyway, I managed to steal and bastardize some code I found somewhere, and ended up with this:
#include <iostream>
#include <functional>
#include <queue>
class Event
{
public:
int timeOfCompletion;
std::function<void()> function;
inline bool operator<(const Event& target) const
{
return target.timeOfCompletion < timeOfCompletion;
}
};
class System
{
public:
int someValue;
std::priority_queue<Event> funcs;
System()
{
someValue = 100;
}
template<typename Func, typename...Args>
void addFunctionToQueue(const int t , const Func&& myFunc, Args&&... myArgs)
{
Event newEvent;
std::function<void()> func = std::bind( std::forward<Func>(myFunc), std::ref(myArgs)...);
newEvent.function = func;
newEvent.timeOfCompletion = t;
funcs.push(newEvent);
}
void runAllFunctions()
{
while(!funcs.empty())
{
Event func = funcs.top();
funcs.pop();
func.function();
}
}
static void doStaticFunction(int a)
{
std::cout <<"I would like to change someValue here, but can't :-(\n";
//someValue -= a;//invalid
}
void doNonStaticFunction(int a)
{
someValue -= a;
std::cout <<"Set someValue to " << someValue << "\n";
}
};
int main()
{
System newSystem;
newSystem.doNonStaticFunction(5);
newSystem.addFunctionToQueue(5, System::doStaticFunction, 1);
newSystem.runAllFunctions();
//newSystem.addFunctionToQueue(5, newSystem.doStaticFunction, 1);// is invalid
//newSystem.addFunctionToQueue(5, System::doNonStaticFunction, 1);// is invalid
//newSystem.addFunctionToQueue(5, newSystem.doNonStaticFunction, 1);// is invalid
std::cin.ignore();
return 0;
}
Anyhow, how can I get the "addFunctionToQueue" function to work with non-static functions? I thought I had more questions, but I think if I can get that one answered, my other problems will hopefully be solved...
Remove a const qualifier from the Func parameter.
template<typename Func, typename...Args>
void addFunctionToQueue(int t , Func&& myFunc, Args&&... myArgs)
// ~~~^ no const
Rationale: When using a forwarding reference (or an lvalue reference) type with a template argument deduction, a const qualifier is automatically deduced (depending on the argument's qualifiers). Giving it explicitly prevents the compiler from adding it to the Func type itself, which results in an error when you try to std::forward<Func>. That said, you would need to write std::forward<const Func> instead to avoid the compiler error, but still, that would make no sense, as const T&& is not a forwarding reference.
Non-static member functions require an object for which they will be called, just like you write a.foo(), not foo().
newSystem.addFunctionToQueue(5, &System::doNonStaticFunction, &newSystem, 1);
// ~~~~~~~~~^ context
In C++03, when you were to wrap a bunch of C functions in a class to create an 'auto object', you had to customize the object to the type of functions it encapsulated. As an example, to wrap a windows file HANDLE, you needed to call CloseHandle() in the destructor and CreateFile() in the constructor. The constructor would need to mimic the function signature of the CreateFile() function, sans the file HANDLE variable (since it's being managed).
Anyway, what I'd like to know is if it's possible to use the new features of C++11 to create a single generic class that can be used to wrap any type of resource by only providing an implementation for creation and deletion?
One problem I foresee is that the creation function, such as noted above with CreateFile(), can taken any number of parameters. Is there a way to auto-magically generate a templated constructor that mimics the signature of the function? Variadic Parameters come to mind, but I have not yet used them.
Has anyone tried writing something like this?
EDIT: Some code to help illustrate (pseudo):
template<typename Res, FunctionPtrToCreatorFunc Func, typename... Arguments>
class creator
{
public:
operator()(Res &r, Arguments... Args)
{
Func(r, /*use args?*/ Args); // Allocate resource, ie. CreateFile(r, args)
}
};
template<typename Res, FunctionPtrToDeleterFunc Func>
class deleter
{
operator()(Res &r)
{
Func(r); // delete the resource, ie. CloseHandle(r)
}
};
Then this will be the implementation of my super auto object:
template<typename Res, typename Creator, typename Deleter>
class auto_obj
{
public:
auto_obj(/*somehow copy Args from Creator class?*/)
{
Creator(_res, /*args?*/);
}
~auto_obj()
{
deleter(_res);
}
Res _res;
};
Yes, this has a similar structure to shared_ptr or unique_ptr, but instead the constructor will be the one that creates the resources by developer written creator and deleter classes. I have a feeling that std::bind may play a role in this, but I have never used it.
Here is a stab at it:
#include <utility>
#include <type_traits>
#include <cstddef>
A more friendly way to wrap up a function. I move the signature boilerplate to this template, instead of messing up the actual RAII class below. This also allows full fledged function objects to be used, as well as functions, in the RAII class below:
template< typename FuncSig, FuncSig func >
struct Functor {
template<typename... Args>
auto operator()(Args&&... args) const
-> decltype( func(std::forward<Args>(args)...) )
{ return ( func(std::forward<Args>(args)...) ); }
};
One operation that is needed for more than basic functionality is the ability to "null" a handle, allowing invalid handles to exist, and allowing handles to be moved around. Zeroer is my default function object for "null"ing a handle:
struct Zeroer {
template<typename T>
void operator()( T& t ) const {
t = 0;
}
};
RAII_handle herself. You pack the creation and destruction signatures into it, and it forwards construction to the underlying data. .close() lets you close the RAII_handle early, which is a common requirement in practice. You access the underlying data via operator* or operator->, and while this makes it look pointer-like, RAII_handle does not obey pointer semantics. It is a move-only type.
template< typename T, typename Creator, typename Destroyer, typename Nuller=Zeroer >
struct RAII_handle {
RAII_handle( std::nullptr_t ):
data()
{
Nuller()(data);
}
RAII_handle( RAII_handle const& ) = delete;
RAII_handle( RAII_handle && o ):data(std::move(o.data)) {
Nuller()(o.data);
}
RAII_handle& operator=( RAII_handle const& ) = delete;
RAII_handle& operator=( RAII_handle && o ) {
data = std::move(o.data);
Nuller()(o.data);
return *this;
}
template<typename... Args>
RAII_handle( Args&&... args ):
data( Creator()(std::forward<Args>(args)...) )
{}
auto close()->decltype( Destroyer()(std::declval<T&>()) ) {
auto retval = Destroyer()(data);
Nuller()(data);
return retval;
}
~RAII_handle() {
close();
}
T& get() { return data; }
T const& get() const { return data; }
T& operator*() { return get(); }
T const& operator*() const { return get(); }
T* operator->() { return &get(); }
T const* operator->() const { return &get(); }
private:
T data;
};
Now, some test code. My file handles will be unsigned char, and opening/closing will simply test if things are not working right.
#include <iostream>
typedef unsigned char HANDLE;
HANDLE CreateFile( char const* name ) {
std::cout << name << "\n";
return 7;
}
bool CloseFile( HANDLE h ) {
if (h) {
--h;
std::cout << (int)h << "\n";
return true;
} else {
std::cout << "already closed\n";
return true;
}
}
Once you have your open/close functions or function objects, here is how you make the type of the FileHandle:
typedef RAII_handle< HANDLE, Functor< HANDLE(*)( char const* ), CreateFile >, Functor< bool(*)(HANDLE), CloseFile > > FileHandle;
You can support entire overload sets by simply creating a function object that forwards to a fixed function name, instead of to a fixed function pointer. Basically take Functor above, remove the template signature and pointer, and replace the use of func with actual use of your function name.
Suddenly your function object represents not calling one function, but calling an entire overload set.
Fancier work can even support multiple functions, allowing one function object to support calling either CreateFile or CreateFileEx depending on what arguments are passed in.
And here is our trivial test code:
int main() {
FileHandle bob("hello.txt");
HANDLE value = *bob; // get the HANDLE out of the FileHandle
bob.close(); // optional, to close early
}
Requirements: your CloseFile must accept Nuller()(std::declval<T&>()) and not behave badly. The default Nuller()(...) just assigns zero to your T, which works for many handle types.
It supports move semantics, allowing you to return these from a function, but I didn't include a Copier argument (which I'd expect would be required for any RAII objects that can be copied).
Live example with very slightly different code.