C++ 11 get pointer of a std::function - c++

I want to store and identify std::function objects in a std::map.
To identify I want to use the std::function::target.
I can't get the pointer from std::function::target if I use std::bind to bind to a member function from a class.
#include <functional>
#include <iostream>
using namespace std;
void normal_fun(int a)
{
std::cout << "hello\n"<<a;
}
class testclass
{
public:
int b;
void mytest(int a)
{
b = a;
}
};
uintptr_t getFuncAddress(std::function<void(int)> &f)
{
uintptr_t returnAddress = reinterpret_cast<uintptr_t>(f.target<void(*)(int)>());
return returnAddress;
}
int main()
{
testclass c;
std::function<void(int)> f1 = bind(&testclass::mytest,&c, placeholders::_1);
std::function<void(int)> f2 = normal_fun;
auto addrF1 = getFuncAddress(f1);
auto addrF2 = getFuncAddress(f2);
}
How can I achieve what I want to do?

A std::function is not a function pointer. It is not even a pointer.
If you know what type is stored in a std::function, you can get a pointer to what it stores. Note that the pointer here is not the function pointer, but a pointer to the function pointer.
If you do not know what type it stores, you cannot.
If you want < or == or hash (etc), std::function does not provide this for you. It type erases (), copy, move, destruction, typeid, and cast-back-to-original.
You can use type erasure techniques to augment a std::function with those operations; note that type erasure on binary operations is a touch trickier than type erasure is in general.
Type erasing something shouldn't be your first go-to when solving a problem, but it will solve your problem. There are articles on type erasure in SO documentation for C++. This isn't a beginner subject.
Odds are your underlying problem can be solved in a much simpler way.
In any case, using the type returned from target to order is not a great idea, as it is a pointer to a possibly automatic storage object, or possibly heap storage object; the two of which are going to have significantly different invalidation rules under innocuous operations (like move). A SBO (small buffer optimization) target is going to move with the instance of the std::function, while a heap-allocated one is likely to stay with the state the std::function moves around under std::move-like operations. This is a real mess.

The point of std::function is to give a uniform interface and type for callable objects that meet a given signature. You are expecting it to also provide a uniform key for sorting, but it doesn't do that. There is no way to sort function pointers and arbitrary function objects and callables returned by std::bind. They are completely different things, and comparing them doesn't make sense. All std::function allows you to do is store them and call them.
If you need a sorting mechanism you'll have to invent something yourself, you won't get it from std::function.

I want to store and identify std::function objects in a std::map.
I assume, you want to identify std::function objects (e.g. to call or delete them selectively).
In such situations, I use an additional key e.g. a simple unsigned.
A global function may be used:
typedef unsigned Key;
Key genId()
{
static Key id = 0;
return ++id;
}
Now, the std::function objects can be paired with this key. The API may grant that access to paired std::function objects can be done using the key exclusively.

f.target<void(*)(int)>
Is wrong, because the type returned by bind is not void(*)(int), so the target will never return a non-null pointer. Bind does not return a function pointer. It returns some object of implementation specified type.
The type can be acquired with decltype. This is a bit perverse, but should be correct:
f.target<decltype(bind(
&testclass::mytest,
(testclass*)nullptr,
placeholders::_1)
)>
but i have the Problem that i didn't know in getFuncAddress if i have testclass or myOtherClass or someone else Class
You can only use std::function::target if you know the type of the wrapped object. If the number of choices is limited, then you can try to get the target with each type until non-null is returned. For an arbitrary unknown type, std::function::target can not be of any use for you.
I want to store and identify std::function objects in a std::map
I think you will have to use some external key, that cannot be extracted from the std::function. This means that if you wish to prevent duplicates, you also need an external method of guaranteeing a unique mapping from key to the function.

Related

Is there any way to go back from `std::function` to a pointer?

Imagine the following scenario:
typedef std::function<float(float)> A;
typedef float(*B)(float);
A foo();
void bar(B b);
You wish to do something along the lines of:
bar(foo());
Obviously this does not work. Mainly because A can contain a state and B is a function pointer. What if we know that A does not contain a state and we wish to somehow take it's "meaning" and put it into something that can be passed for a B?
Is it impossible?
If you can ensure that the callable object stored in A is a function pointer or a lambda with an empty capture list, you can simply get a function pointer in this way:
foo().target<B>();
In general, a std::function can "box" some closure (e.g. the value of some lambda function). And a closure contains both code and data (the closed values). So I believe that you cannot portably convert it to a naked function pointer. BTW, because conceptually closures are mixing code and data languages not providing them (like C) practically requires callbacks (i.e. the convention to pass every function pointer with some additional data, look into GTK for a concrete example).
Some implementation specific tricks might make a trampoline function on the stack (e.g. dynamically generate, perhaps with asmjit, some machine code containing a pointer to the closure, etc.). But this is not portable and system specific (in particular because the stack needs to be executable)
What if we know that A does not contain a state and we wish to somehow take it's "meaning" and put it into something that can be passed for a B?
Even that isn't sufficient. std::function provides a target() member function, that if you know the exact type of the underlying functor, you can get it back. So we can do, for instance:
void print(int i) { std::cout << i; }
std::function<void(int)> f = print;
auto ptr = f.target<void(*)(int)>(); // not null
(*ptr)(42); // works
However, even if our functor f doesn't contain state, that doesn't mean that its underlying type is precisely void(*)(int). It could be a completely different function pointer, in which case we wouldn't be able to pull it out:
int square(int i) { return i*i; }
f = square;
ptr = f.target<void(*)(int)>(); // nullptr!
Or it could be a lambda, in which case we wouldn't even be able to name the type, much less pull it out:
f = [](int i){ std::cout << i; }; // same as print, right?
ptr = f.target<void(*)(int)>(); // ... nope :'(
Basically, type erasure is really type erasure. If you need the original underlying type, that's likely indicative of a bad design.

How to get numeric data from a member function pointer for a hash? [duplicate]

How can i hash (std::tr1::hash or boost::hash) a c++ pointer-to-member-function?
Example:
I have several bool (Class::*functionPointer)() (not static) that point to several diferent methods of the class Class and i need to hash those pointer-to-member-function.
How can i do that?
Also how can i compare (std::less) those member function pointers so i can store them in a std::set?
All C++ objects, including pointers to member functions, are represented in memory as an array of chars. So you could try:
bool (Class::*fn_ptr)() = &Class::whatever;
const char *ptrptr = static_cast<const char*>(static_cast<const void*>(&fn_ptr));
Now treat ptrptr as pointing to an array of (sizeof(bool (Class::*)())) bytes, and hash or compare those bytes. You can use unsigned char instead of char if you prefer.
This guarantees no false positives - in C++03, pointers to member functions are POD, which means among other things that they can be copied using memcpy. This implies that if have the same byte-for-byte values, then they are the same.
The problem is that the storage representation of member function pointers could include bits which do not participate in the value - so they will not necessarily be the same for different pointers to the same member function. Or the compiler might, for some obscure reason, have more than one way of pointing to the same function of the same class, which are not byte-wise equal. Either way you can get false negatives. You'll have to look into how member function pointers actually work on your implementation. It must implement operator== for member function pointers somehow, and if you can find out how then you can probably figure out an order and a hash function.
That's potentially hard: member function pointers are awkward, and the storage is likely to include different amounts of non-participating "slack space" according to what kind of function is pointed to (virtual, inherited). So you'll probably have to interact quite significantly with your compiler's implementation details. This article might help get you started: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
A cleaner alternative might be to do a linear search through an array in order to "canonicalise" all your function pointers, then compare and hash based on the position of the "canonical" instance of that function pointer in your array. Depends what your performance requirements are. And even if there are requirements, does the class (and its derived classes) have so many functions that the linear search will take that long?
typedef bool (Class::*func)();
vector<func> canon;
size_t getIndexOf(func fn_ptr) {
vector<func>::iterator it = find(canon.begin(), canon.end(), fn_ptr);
if (it != canon.end()) return it - canon.begin();
canon.push_back(func);
return canon.size() - 1;
}
I could not cast the pointer (in Microsoft compiler 2010)as described in previous answer but this works for me:
static string fmptostr(int atype::*opt)
{
char buf[sizeof(opt)];
memcpy(&buf,&opt,sizeof(opt));
return string(buf,sizeof(opt));
}
About bitwise identity of the pointer, it can be bitwise so it seems if appropriate compiler switches are used. At least this is true for Microsoft compiler E.g
using #pragma pointers_to_members
and a switch.../vmg
If your member function pointer is unique, which is true in most of cases for callback-based subscriptions, then you can use the tick with type_index, which uniqueness is guaranteed by uniqueness of type (i.e. Class::Method) in your program, and it is suitable to be stored in unordered_map, i.e.
struct MyEvent {
using fn_t = std::function<void(MyEvent &)>;
using map_t = std::unordered_map<std::type_index, fn_t>;
template <typename Handler>
void subscribe(Object& obj, Handler&& handler) {
fn_t fn = [&, handler = std::move(handler)](MyEvent& event) {
(obj.*handler)(event);
}
std::type_index index = typeid(Handler);
subscribers.emplace(std::move(index), std::move(fn));
}
void fire() {
for(auto& pair: subscribers) {
auto& fn = pair.second;
fn(*this);
}
}
map_t subscribers;
}
And the subscription and fire event example:
MyEvent event;
MyObject obj = ...;
event.subscribe(obj, &MyObject::on_event );
...
event.fire();
So, example above gives you class/method uniqueness, and if you need object/method uniqueness, then you should have an struct, which provides combined hash, assuming that there is std::hash<MyObject> and there is already std::hash<std::type_index> for a member function pointer.

C++11 std::function and std::reference wrapper used for sorting std::set

I have a C++ class, and one of its fields is a std::set of objects. I want to write my own comparison function, or let the user specify one. In C++11 there's a new way to handle generic function types: std::function. It works with function pointers, member function pointers, lambda functions, etc.
I tried to write a simple experiment program but it keeps craching all the time, even when I do what the C++11 Wikipedia article suggets. Maybe I just don't get how std::function and std::ref are supposed to be used.
Anyway, the point is that when I created a std::function from a simple lambda function and made it a class member, the sizeof of the class grew by 22. When I created a std::function from a pointer to a global function, this std::function's sizeof was 32. So the size is big. I'm going to have many objects using the same comparison function, so I prefer to have one function used by all of them.
I have two ideas, tell me what you think. One idea, use std::ref to store a reference to a function, this way I can define one function and many objects will use it to compare the std::set elements. Second idea: if it doesn't work like that, or the resulting function object is too big anyway, maybe I can use a shared_ptr.
You may wonder: why not have one static std::function member? The answer: because then ALL objects will use the same comparison function. I want to be able to have, for example, 1000 objects, with 400 using one comparison function and 600 using a different comparison function.
Example:
class MyClass
{
public:
private:
std::function<bool (int, int)> compare;
std::set<int> set;
};
Now how do I make the std::set use the std::function, and have many MyClass objects use the same function?
I'd like to be able to change the comparison function during run-time, so that the user would be able to choose the ordering of the objects in the set (which are displayed by GUI).
The standard way to represent shared ownership is using std::shared_ptr. That adds a bit more overhead, forcing you to allocate the std::function on the heap, but a shared_ptr is smaller than a std::function and it will correctly manage its lifetime so while any objects are still using the function object it will be kept alive and will automatically be destroyed when no longer needed.
As you suggest, a reference_wrapper referring to the shared function can be used as the set's comparison object, because a reference_wrapper is callable if it wraps a callable type.
class MyClass
{
typedef std::function<bool (int, int)> func_type;
public:
MyClass(std::shared_ptr<func_type> const& f)
: compare(f), set( std::ref(*f) )
{ }
private:
std::shared_ptr<func_type> compare;
std::set<int, std::reference_wrapper<func_type>> set;
};
A reference_wrapper cannot be null (like a reference) so you must construct the std::set with a valid reference_wrapper object.
Since the std::reference_wrapper in the std::set just holds a non-owning pointer to the std::function, you need to be careful to update the set's comparison object at the same time as updating the shared_ptr, or you could drop the last reference to the function, so the shared_ptr would destroy it, leaving a dangling pointer in the set. That could be done like this:
void MyClass::replace_cmp(std::shared_ptr<func_type> const& f)
{
set = std::set<int, std::reference_wrapper<func_type>>( std::ref(*f) );
compare = f;
}
You tell the set to use your comparison function in your constructor initializer list:
class MyClass
{
public:
template<typename Fc>
MyClass(Fc compare_func)
: compare(compare_func), // Initialize the comparison function
set(compare) // Tell the set to use out function for comparison
{}
};

How to convert an object instance to shared_ptr instance

Suppose I had two shared_ptr types such as
boost::shared_ptr<ObjA> sptrA;
boost::shared_ptr<ObjB> sptrB;
Now suppose that sptrA->SomeMethod() returned a simple ObjB type (not a shared ptr). Is it possible for me to store that type somehow in sptrB ? So that I could do something like this so that the returned type instance is automatically converted to boost_shared ptr
sptrB = sptrA->SomeMethod();
I asked this question just of curiosity and whether it is possible or not ?
The most standard way of creating boost:shared_ptr objects is to use the make_shared function provided by Boost:
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
struct A {};
A generator() {
return A();
}
int main()
{
using namespace boost;
shared_ptr<A> p = make_shared<A>(generator());
return 0;
}
Since the generator() function returns an A object by value, the syntax above implies that new is invoked with the copy contructor of A, and the resulting pointer is wrapped in a shared-pointer object. In other words, make_shared doesn't quite perform a conversion to shared pointer; instead, it creates a copy of the object on the heap and provides memory management for that. This may or may not be what you need.
Note that this is equivalent to what std::make_shared does for std::shared_ptr in C++11.
One way to provide the convenient syntax you mentioned in your question is to define a conversion operator to shared_ptr<A> for A:
struct A {
operator boost::shared_ptr<A>() {
return boost::make_shared<A>(*this);
}
};
Then you can use it as follows:
shared_ptr<A> p = generate();
This will automatically "convert" the object returned by the function. Again, conversion here really means heap allocation, copying and wrapping in a shared pointer. Therefore, I am not really sure if I'd recommend defining such a convenience conversion operator. It makes the syntax very convenient, but it, as all implicit conversion operators, may also mean that you implicitly cause these "conversions" to happen in places you didn't expect.
Since C++ 11 you can use std::make_shared<T>() function (link)
Example:
int a = 10;
std::shared_ptr<int> shared_a = std::make_shared<int>(a);
This depends on precisely what ObjA::SomeMethod returns - a copy, a reference or a pointer. In the first two cases it would not be feasible to wrap it into a shared_ptr (because shared_ptr needs a pointer).
The third case is possible, but you must proceed with caution. Make sure that once you wrap a pointer to an object into a shared_ptr, no one else attempts to manage the lifetime of that object.
For example, if you return a raw pointer, wrap it into a shared pointer and then, at some point later in the program, someone deletes that same pointer, you will have a problem.

Have the ideas behind the Fast Delegate (et al) been used to optimize std::function?

There have been proposals for C++ "delegates" which have lower overhead than boost::function:
Member Function Pointers and the Fastest Possible C++ Delegates
Fast C++ Delegate
The Impossibly Fast C++ Delegates
Have any of those ideas been used to implement std::function, resulting in better performance than boost::function? Has anyone compared the performance of std::function vs boost::function?
I want to know this specifically for the GCC compiler and libstdc++ on Intel 64-bit architectures, but information on other compilers is welcome (such as Clang).
In libstdc++'s std::function we use a union type that is suitably sized and aligned to store pointers, function pointers or pointers to member functions. We avoid a heap allocation for any function object that can be stored in that size and alignment, but only if it is "location invariant"
/**
* Trait identifying "location-invariant" types, meaning that the
* address of the object (or any of its members) will not escape.
* Also implies a trivial copy constructor and assignment operator.
*/
The code is based on the std::tr1::function implementation and that part hasn't changed significantly. I think that could be simplified using std::aligned_storage and could be improved by specializing the trait so that more types are identified as location invariant.
Invoking the target object is done without any virtual function calls, the type erasure is done by storing a single function pointer in the std::function which is the address of a function template specialization. All operations are done by calling that function template through the stored pointer and passing in an enum identifying what operation it is being asked to perform. This means no vtable and only a single function pointer needs to be stored in the object.
This design was contributed by the original boost::function author and I believe it is close to the boost implementation. See the Performance docs for Boost.Function for some rationale. That means it's pretty unlikely that GCC's std::function is any faster than boost::function, because it's a similar design by the same person.
N.B. our std::function doesn't support construction with an allocator yet, any allocations it needs to do will be done using new.
In response to Emile's comment expressing a desire to avoid a heap allocation for a std::function which holds a pointer to member function and an object, here's a little hack to do it (but you didn't hear it from me ;-)
struct A {
int i = 0;
int foo() const { return 0; }
};
struct InvokeA
{
int operator()() const { return a->foo(); }
A* a;
};
namespace std
{
template<> struct __is_location_invariant<InvokeA>
{ static const bool value = true; };
}
int main()
{
A a;
InvokeA inv{ &a };
std::function<int()> f2(inv);
return f2();
}
The trick is that InvokeA is small enough to fit in the function's small object buffer, and the trait specialization says it's safe to store in there, so the function holds a copy of that object directly, not on the heap. This requires a to persist as long as the pointer to it persists, but that would be the case anyway if the function's target was bind(&A::foo, &a).
As noted in the comments, std::function is only an interface, and different implementations may do different things, but it's worth noting that the standard does actually have something to say about this matter. From 20.8.11.2.1/5 (which looks more like an IP address than a part of the standard):
Note: Implementations are encouraged to avoid the use of dynamically
allocated memory for small callable objects, for example, where f’s
target is an object holding only a pointer or reference to an object
and a member function pointer. —end note
This is the standard's way of encouraging implementers to employ the "small function optimization," which was motivated by the cited articles on delegates. (The articles themselves don't actually talk about delegates in the .NET sense. Rather, they use the term "delegate" to mean bound member functions.)