I can't seem to declare a generic pointer to function.
Having these 2 functions to be called:
void myfunc1(std::string str)
{
std::cout << str << std::endl;
}
struct X
{
void f(std::string str){ std::cout<< str << std::endl;}
};
and these two function callers:
typedef void (*userhandler_t) (std::string);
struct example
{
userhandler_t userhandler_;
example(userhandler_t userhandler): userhandler_(userhandler){}
void call(std::string str)
{
userhandler_(str);
}
};
template<typename func_t>
void justfunc(func_t func)
{
func("hello, works!");
}
when I try to use them with boost::bind to call the member function they give me compile errors.
this works:
example e1(&myfunc1);
e1.call("hello, world!");
justfunc(&myfunc1);
this doesn't:
X x;
example e2(boost::bind(&X::f, &x, _1));
e2.call("hello, world2!");
justfunc(boost::bind(&X::f, &x, _1));
How is this supposed to be done?
boost::bind creates objects that behave like functions, not actual function pointers. Use the Boost.Function library to hold the result of calling boost::bind:
struct example
{
boost::function<void(std::string)> userhandler_;
...
};
Related
I want to pass pointers of some functions to a template class to use them later. I was wondering if:
Does it make a possibly (speed-wise) beneficial difference if I make these functions inline?
Functions themselves are possibly one line wrapper for another functions like the example below:
//inline ?
void func_wrapper_1(){
func1(arg1);
}
//inline ?
void func_wrapper_2(){
func2(arg2);
}
and the class template is like the example below:
template<void(*f1)(), void(*f2)()>
class caller{
public:
static void func(int v){
if(v) {
(*f1)();
}else{
(*f2)();
}
}
};
And later on in the main function it will be used like the example below:
caller<func_wrapper_1,func_wrapper_2>::func(0);
caller<func_wrapper_1,func_wrapper_2>::func(1);
I know that every things depends on compiler and compiling option, but lets assume compiler accepts to make these functions inline.
Whether or not a compiler will be smart enough to inline a given situation is up for grabs but I think it may be possible by creating Callable Types by overloading the function call operator.
Something like this:
template<typename Func1, typename Func2>
class caller{
public:
static void func(int v){
if(v) {
// Func1() - creates an object of type Func1
// that object is 'called' using the '()' operator
Func1()();
}else{
Func2()();
}
}
};
struct CallableType1
{
// overloading the function call operator makes objects of
// this type callable
void operator()() const { std::cout << "callable 1" << '\n'; }
};
struct CallableType2
{
void operator()() const { std::cout << "callable 2" << '\n'; }
};
int main()
{
caller<CallableType1, CallableType2> cc;
cc.func(2);
}
I have a C-style function, which stores another function as an argument. I also have an object, which stores a method that must be passed to the aforementioned function. I built an example, to simulate the desired situation:
#include <functional>
#include <iostream>
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
std::function<void(int)> f;
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
TestClass t;
t.f = std::bind(&TestClass::foo, &t, std::placeholders::_1);
foo( t.f.target<void(int)>() );
return 0;
}
What is expected is that it will be shown on screen "2". But I'm having trouble compiling the code, getting the following message on the compiler:
error: const_cast to 'void *(*)(int)', which is not a reference, pointer-to-object, or pointer-to-data-member
return const_cast<_Functor*>(__func);
As I understand the use of "target", it should return a pointer in the format void () (int), related to the desired function through std :: bind. Why didn't the compiler understand it that way, and if it is not possible to use "target" to apply what I want, what would be the alternatives? I don't necessarily need to use std :: function, but I do need the method to be non-static.
This is a dirty little hack but should work
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
static TestClass* global_variable_hack = nullptr;
void hacky_function(int x) {
global_variable_hack->foo(x);
}
int main() {
TestClass t;
global_variable_hack = &t;
foo(hacky_function);
return 0;
}
//can also be done with a lambda without the global stuff
int main() {
static TestClass t;
auto func = [](int x) {
t->foo(x); //does not need to be captured as it is static
};
foo(func); //non-capturing lambas are implicitly convertible to free functions
}
I want to make an array of known size of class functions. To do so, I've tried using typedef, but it hasn't been working out so far.
Also, some functions take no arguments ex. F(), but others do ex. G(int n), and in the typedef, I don't know how to tell it to accept no arguments for some (tried void but it says it is not a type), and to accept arguments for others.
class myClass
{
// An array of void functions
typedef void(myClass::*arrayOfFunctions)();
private:
arrayOfFunctions array[3] = { &myClass::F, &myClass::G, &myClass::H };
void F() { do stuff; }
void G(int n) { do stuff involving n; }
void H() { do stuff; }
};
What I have tried:
I have successfully made an array of void functions in a main with no classes involved which I can call when wanted, so part of the problem seems to be implementing this in a class and using its class functions.
// This works:
typedef void(*arrayOfFunctions)();
void Action1()
{
// stuff 1
}
void Action2()
{
// stuff 2
}
void Action3()
{
//stuff3
}
int main()
{
arrayOfFunctions functionArray[] = { Action1, Action2, Action3 };
// Call Action1
functionArray[0]();
return 0;
)
As was mentioned in comments, it is not possible directly. You cannot store objects of different type in the same array. However, there are ways to achieve what you want. How to get there very much depends on details. Latest when you call the function you need to know how many parameters to pass.
In your example one possibility is to refactor to have only methods with no parameters:
class myClass {
using memFun = void(myClass::*)();
void set_n(int x) { n = x; }
private:
memFun array[3] = { &myClass::F, &myClass::G, &myClass::H };
void F() { do stuff; }
void G() { do stuff involving n; }
void H() { do stuff; }
int n;
};
I changed the name of the alias, because it is just the type of a function pointer not an array. using is easier to read than typedef (it follows the more common x = something style).
When you call the function G the parameter n has to come from somewhere, so instead of passing it directly you can call set_n before iterating the array and call all mehtods without parameter.
It is not clear how you want to use such an array. If you know an element index at compile time, then you could probably use a std::tuple with template argument deduction. For example:
class my_class {
public:
template<std::size_t n, class... Args>
decltype(auto) call_fn(Args&&... args) {
constexpr auto ptrs = get_fn_pointers();
return std::invoke(std::get<n>(ptrs), this, std::forward<Args>(args)...);
}
private:
static constexpr auto get_fn_pointers() {
return std::tuple(&my_class::f, &my_class::g, &my_class::h);
}
void f() {
std::cout << "f()\n";
}
void g(int n) {
std::cout << "g(" << n << ")\n";
}
int h() {
std::cout << "h() => ";
return 9102;
}
};
int main() {
my_class c;
c.call_fn<0>(); // Output: f()
c.call_fn<1>(2019); // Output: g(2019)
std::cout << c.call_fn<2>(); // Output: h() => 9102
}
Since function pointers need to know what arguments are supplied ahead of time I don't know how to do this.
Essentially I want a list of work. Each entry is a function to be called with specific arguments. I.e. I want to add foo(3, "abcd") to the work list, and then later bar(&h). That is, I don't know beforehand what types of functions will be added.
Later I will the iterate over this list and do the function calls specified.
Can this be implemented?
You're looking for std::function and either lambdas, or std::bind.
std::function is a wrapper for an arbitrary callable. You can store anything in it on which you can call operator() with the appropriate arguments.
One thing you can store in it are lambdas: you'd encapsulate the call and arguments into a non-argument lambda and call that.
Another thing you can store is the result of std::bind. std::bind is effectively a metafunction: it takes a function f and arguments as input, and returns a function object whose invocation results in invoking f on the arguments.
Here's how you could apply this to your case. The common setup:
std::vector<std::function<void()>> workList;
fillWorkList(workList);
for (auto& f : workList)
f();
And here are two possible implementations of fillWorkList. One with std::bind:
void fillWorkList(std::vector<std::function<void()>>& workList)
{
workList.push_back(std::bind(foo, 3, "abcd"));
workList.push_back(std::bind(bar, &h));
}
And one with lambdas:
void fillWorkList(std::vector<std::function<void()>>& workList)
{
workList.push_back([]() { foo(3, "abcd"); });
workList.push_back([]() { bar(&h); });
}
A std::function<void()> represents something that can be invoked, and returns nothing.
The clearest thing to store in it is a lambda.
std::function<void()> f = []{ foo(3, "abcd"); };
stores "call foo( 3, "abcd" ); in the std::function called f.
We can build a list of them -- a std::deque or std::vector -- and call them at a later time.
You can capture state in a lambda by putting what you want to capture within the []s:
std::function<void()> g = [h]{ bar(&h); };
This copies h into the lambda, then calls bar with a pointer to h. Sometimes you'll want h to be mutable:
std::function<void()> g = [h]()mutable{ bar(&h); };
You can also have lambdas that store references to variables. This is dangerous, as you are responsible for lifetime, and if you are storing the lambdas within std::functions then storing those in a container, lifetime may not be simple.
In C++14 you can even put expressions in the []s.
std::function<void()> behaves like a value. You invoke it with (), just like calling a function with signature void().
Using std::bind instead of lambdas is technically possible, but std::bind has many strange quirks and the code generated is usually less clear and errors are almost always unreadable. Don't do it.
You can also do this with a custom function object.
struct custom {
std::string s;
void operator()() const {
foo( 3, s );
}
};
Then std::function<void()> f = custom{ "abcd" }; is another way to say you'll invoke foo with 3, std::string("abcd") later when you f() on f.
Here is a solution, using a parameter pack, and perfect forwarding that allows for add(foo, 3, "abcd") to be used:
#include <functional>
#include <string>
#include <iostream>
#include <vector>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Worklist {
public:
template <typename ...Args>
void add(Args&&... args) {
worklist.push_back(std::bind(std::forward<Args>(args)...));
}
void do_all()
{
for(auto& i : worklist) {
i();
}
}
std::vector<std::function<void(void)>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add(foo, 3, "abcd");
worklist.add(bar,&h);
worklist.do_all();
}
It is possible to write a class that will accept lambdas as the tasks without using std::bind or std::function.
Here, a std::unique_ptr is used to store each of the lambdas:
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Generic_Callable {
public:
~Generic_Callable() = default;
virtual void call() = 0;
};
template <typename T>
class MyCallable : public Generic_Callable {
public:
MyCallable(T &&t) : ptr{std::make_unique<T>(std::move(t))} {}
void call() override
{
(*ptr)();
}
std::unique_ptr<T> ptr;
};
class Worklist {
public:
template <typename T>
void add(T &&t)
{
worklist.push_back(std::make_unique<MyCallable<T>>(std::move(t)));
}
void do_all() {
for(auto& i : worklist)
i->call();
}
std::vector<std::unique_ptr<Generic_Callable>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add([]() {foo(3, "abcd"); });
worklist.add([&h]() {bar(&h); });
worklist.do_all();
}
Is there a way in C++ to make an "untyed" function pointer ?
For example:
// pointer to global function
void foo( void (*fptr)() );
// pointer to member
void foo( void (Bar::*fptr)() );
Is there a way I can remove the class on which the member is ? So that I could do something like this:
void foo( void ("any type"::*fptr)(), "same type as for the pointer" &instance );
And then, in foo, I would like to store that pointer in a list, so that I can iterator over the list and call the function/member pointed to, regardless of what class it belongs to. Of course I'd need a list of instances on which to call the function.
Thx.
You can use a template.
template<typename T> void foo( void(T::*)(), T&) { ... }
However, people prefer to go for the function object approach. You can do this dynamically or statically.
void foo(std::function<void()> func) {
// std::bind is used to make this out of a member function
}
template<typename T> void foo(T t = T()) {
t(); // This is the best approach.
}
Edit: Some examples.
void foo(std::function<void()> func) {
std::cout << "In example one ";
func();
}
template<typename T> void foo(T t = T()) {
std::cout << "In example two ";
t();
}
class some_class {
public:
void func() { std::cout << "in ur function!\n"; }
};
int main(void)
{
some_class* ptr = NULL;
struct tempfunctor {
tempfunctor(some_class* newptr)
: ptr(newptr) {}
some_class* ptr;
void operator()() { return ptr->func(); }
};
foo(tempfunctor(ptr)); // Calls example two
foo(std::function<void()>(tempfunctor(ptr))); // Calls example one
foo(std::function<void()>(std::bind(&some_class::func, ptr)); // I'm not that familiar with bind, it looks something similar to this.
std::cin.get();
}
This is the idiom called the function object idiom, used heavily in STL and other high-quality libraries. The compile-time template is cleaner but the std::function can be bound at runtime.
Edit # OP: I didn't quite see your list requirement in there. A std::function<void()> is your best choice here.
The following seems to work fine with g++ and MSVC:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
void foo( boost::function<int()> f )
{
cout << "f() = " << f() << endl;
}
template< class Type >
void foo( int (Type::*f)() const, Type const& o )
{
foo( boost::bind( f, boost::ref( o ) ) );
}
int func1() { return 1; }
struct S { int func2() const { return 2; } };
int main()
{
foo( func1 );
foo( &S::func2, S() );
}
Disclaimer: I seldom use the Boost stuff and I just typed the above without bothering to check the docs, so possibly it could be expressed more cleanly.
Also note that C++0x standard library offers the same functionality.
Cheers & hth.,
No. The bound class is an intrinsic part of the member function pointer type.
You can, however, use a member function pointer to a common baseclass, or a template.
Can you use functors in your list?
http://en.wikipedia.org/wiki/Function_object
Have a look at Fast Delegates: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
This is an easy drop-in library that allows you to delegate pretty much anything and at a very high speed.
template <typename T>
void foo( void (T::*fptr)(), T& instance)
{
// ...
}
I'm not going to play expert here, but I think this will work, if not I would like to know why.
You can't have a pointer like that, but you could have a collection of boost::any, and put heterogeneous pointers (or any kind of functors) into it.
You can't do that, and you shouldn't do that even if you could, because it is against the spirit of the language. Create a base class with "fptr" as a pure virtual member, and inherit all your classes from that class.