Can the following function pointer passing be simplified/improved with the use of boost::function and/or boost::bind?
void PassPtr(int (*pt2Func)(float, std::string, std::string))
{
int result = (*pt2Func)(12, "a", "b"); // call using function pointer
cout << result << endl;
}
// execute example code
void Pass_A_Function_Pointer()
{
PassPtr(&DoIt);
}
You can use boost::function<>
to make it possible using different types of callable objects as the function's input.
What follows is an example using C++11 (see the remarks after this example). This is how you would rewrite your function:
#include <functional>
#include <string>
#include <iostream>
void PassFxn(std::function<int(float, std::string, std::string)> func)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
int result = func(12, "a", "b"); // call using function object
std::cout << result << std::endl;
}
These are a couple of functions to test it with:
int DoIt(float f, std::string s1, std::string s2)
{
std::cout << f << ", " << s1 << ", " << s2 << std::endl;
return 0;
}
int DoItWithFourArgs(float f, std::string s1, std::string s2, bool b)
{
std::cout << f << ", " << s1 << ", " << s2 << ", " << b << std::endl;
return 0;
}
struct X
{
int MemberDoIt(float f, std::string s1, std::string s2)
{
std::cout << "Member: " << f << ", " << s1 << ", " << s2 << std::endl;
return 0;
}
static int StaticMemberDoIt(float f, std::string s1, std::string s2)
{
std::cout << "Static: " << f << ", " << s1 << ", " << s2 << std::endl;
return 0;
}
};
And here is the test routine:
int main()
{
PassFxn(DoIt); // Pass a function pointer...
// But we're not limited to function pointers with std::function<>...
auto lambda = [] (float, std::string, std::string) -> int
{
std::cout << "Hiho!" << std::endl;
return 42;
};
PassFxn(lambda); // Pass a lambda...
using namespace std::placeholders;
PassFxn(std::bind(DoItWithFourArgs, _1, _2, _3, true)); // Pass bound fxn
X x;
PassFxn(std::bind(&X::MemberDoIt, x, _1, _2, _3)); // Use a member function!
// Or, if you have a *static* member function...
PassFxn(&X::StaticMemberDoIt);
// ...and you can basically pass any callable object!
}
And here is a live example.
REMARKS:
You can easily change std::function<>
into boost::function<>
and std::bind<>
into boost::bind<>
if you are working with C++03 (in fact, Boost.Function is what inspired std::function<>
and later became part of the Standard C++ Library). In this case, instead of including the <functional>
header, you will have to include the boost/function.hpp
and boost/bind.hpp
headers (the latter only if you want to use boost::bind
).
For a further example that should give you a feeling of the power that std::function<>
/ boost::function<>
gives you through its ability of encapsulating any kind of callable object, also see this Q&A on StackOverflow.