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.
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);
}
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();
}
A reference to array parameter is useful because it prevents decay, allowing you to deduce the size of an array.
template <typename T, std::size_t N>
constexpr std::size_t array_size(T (&) [N]) noexcept
{
return N;
}
But when is this useful?
template<typename T>
void foo(T& t)
{
// we now have a reference to bar
}
void bar() { }
int main()
{
foo(bar);
}
When do we care about preventing function to pointer decay? I'm asking about when this is useful, not why it isn't disallowed.
Like with objects, we us a pointer if “no object” (“no function”) is a sensible value and a reference if we wish to make sure that (unless somebody insists to shoot himself in the foot) there is always a valid object (function) referred to.
Consider the following poor man's function wrapper (wealthy man goes over there).
template<typename>
class Function; // never defined
template<typename ReturnT, typename... ArgT>
class Function<ReturnT(ArgT...)>
{
private:
ReturnT (*func_)(ArgT...);
public:
// Will also accept a 'nullptr'
Function(ReturnT (*func)(ArgT...)) noexcept : func_ {func}
{
}
ReturnT
operator()(ArgT... args)
{
return this->func_(args...);
}
};
Now we can write the following program, which works just fine.
#include <iostream>
int
add(int a, int b)
{
return a + b;
}
int
main()
{
Function<int(int, int)> f {add}; // ok
std::cout << f(5, 7) << std::endl; // ok, prints 12
}
However, we can also write the following program, which doesn't work so nice.
int
main()
{
Function<int(int, int)> f {nullptr}; // compiles fine
std::cout << f(5, 7) << std::endl; // compiles fine, crashes at run-time
}
Instead, if we had replaced the (*func) with (&func) in the template's definition,
// Won't accept a 'nullptr'
Function(ReturnT (&func)(ArgT...)) noexcept : func_ {func}
{
}
the line
Function<int(int, int)> f {nullptr}; // compile-time error
would have triggered a compile-time error.
To me the difference is like between normal variable reference and a pointer. References are nicer to deal with than pointers.
I had a use-case when I to customize a parts of an algorithm. It had some phases and I could switch between several options for each phase. This is of course achievable with pointers, but hey, you can use pointers instead of references pretty much everywhere too.
It looked similar to this:
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(void(&t)()) : barish(t) { };
void fun() {barish();};
private:
void(&barish)();
};
void bar() { cout << "meow\n";}
void bark() { cout << "woof\n";}
int main()
{
Foo foo1(bar);
Foo foo2(bark);
foo1.fun();
foo2.fun();
}
You can customize fun and don't have to deal with dereferencing and asserts that it's not null.
I would like to represent the following code using a UML diagram:
#include <iostream>
#include <boost/bind.hpp>
using namespace std;
class A {
public:
void bar() {std::cout << "A::bar()" << std::endl;}
};
// FUNC should be callable with arguments (int, A*)
template <typename FUNC>
class B {
public:
B(FUNC func, int data) : func_(func), data_(data){}
void operator()(A* ap){func_(data_, ap);}
FUNC func_;
int data_;
};
// object generator uses argument deduction to construct B
template <typename FUNC>
B<FUNC> makeB(FUNC func, int data) {
return B<FUNC>(func, data);
}
struct F {
static void apply(int a, int b, A* ap){
std::cout << "a+b = " << a + b << std::endl;
ap->bar();
}
};
int main() {
A* a = new A;
auto b = makeB(boost::bind(F::apply, 10, _1, _2), 20);
b(a);
}
Here is my first attempt. I think there is some room for improvement:
Should I capture pointers to F and A in the bind attributes or represent them serparately? Currently I'm showing both. I think the syntax for the F::apply attribute is also wrong.
What is the best way to write the signature template for the bind class?
Is there a better way to use decltype in B's template parameter? currently it looks a bit clumsy.
The purpose is to communicate how bind works to people who may not be familiar with it and perhaps convey a little about how bind works internally. The diagram should be as simple as possible so any hacks that are intuitive and not misleading are okay, it doesn't have to conform precisely to the UML standard.
update: This version fixes the type of bind's internal function pointer.
consider this simple and pointless code.
#include <iostream>
struct A {
template<int N>
void test() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a.test<1>();
}
It is a very simple example of a function template. What if however, I wanted to replace A::test with an overloaded operator() to make it a functor?
#include <iostream>
struct A {
template<int N>
void operator()() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a<1>(); // <-- error, how do I do this?
}
Certainly if the operator() took parameters which were dependent on the template, the compiler could possibly deduce the template. But I just can't figure out the proper syntax to specify template parameters with a parameterless functor.
Is there a proper way to do this?
Obviously, this code would work since it bypasses the functor syntax:
a.operator()<1>();
but that kinda defeats the purpose of it being a functor :-P.
You can only call
a.operator()<1>();
but that would not be using a functor. Functors need a non template operator(), as they must be able to be called as varname() and that won't work with your code.
To make it a real functor change your code a template class (functors are classes):
#include <iostream>
template<int N>
struct A {
void operator()() {
std::cout << N << std::endl;
}
};
int main() {
A<1> a;
a();
}
There's not another "direct" way I know other than the:
a.operator()<1>();
syntax. If you're open to changing the code, moving the template parameter to the class would work, or using a (boost|tr1)::bind to make a (boost|tr1)::function object.
You are trying to pass a template parameter to an instance of an object, which as far as I know is not allowed. You can only pass templates parameters to template functions or template objects.
a.test<1>(); and a.operator()<1>(); work because they are serving as template functions.
Use boost::bind (check out boost libraries) to fix it though.
struct A {
void operator()(int n) {
std::cout << n << std::endl;
}
};
int main(int argc, char* argv[]) {
A a;
boost::function<void()> f = boost::bind<void>(a, 1);
f(); // prints 1
return 0;
}
And you don't even have to mess with templates!
You're stuck. Have you considered something like
struct A {
template<int N>
struct B
{
void operator()()
{ std::cout << N << std::endl; }
};
template<int N>
B<N> functor() {return B<N>();}
};
int main()
{
A a;
a.functor<1>()();
}
Nope, there's no way around it. Like you said, you have to either call the operator explicitly (which defeats the purpose), or the template arguments must be able to be deduced by the compiler.