您可以使用boost::function<> 使使用不同类型的可调用对象作为函数的输入成为可能。
下面是一个使用 C++11 的例子(见这个例子后面的备注)。这就是你重写函数的方式:
#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;
}
以下是几个测试它的函数:
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;
}
};
这是测试例程:
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!
}
这是live example。
备注:
如果您正在使用 C++03,您可以轻松地将 std::function<> 更改为 boost::function<> 并将 std::bind<> 更改为 boost::bind<>(事实上,Boost.Function 是启发 std::function<> 并后来成为标准 C++ 库)。在这种情况下,您必须包含 boost/function.hpp 和 boost/bind.hpp 标头,而不是包含 <functional> 标头(后者仅在您想使用 boost::bind 时才包含)。
有关进一步的示例,应该让您感受到std::function<> / boost::function<> 通过封装任何类型的可调用对象的能力为您提供的强大功能,另请参阅this Q&A on StackOverflow。