您可以使用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。
備註:
您可以輕鬆更改std::function<>
爲boost::function<>
和std::bind<>
到boost::bind<>
如果您正在使用C++ 03的工作(其實來自Boost.Function是什麼啓發了std::function<>
後來成爲標準的一部分C++庫)。在這種情況下,不必包含<functional>
標題,而必須包含boost/function.hpp
和boost/bind.hpp
標題(只有在您想使用boost::bind
時才使用後者)。
有關其他示例,應該給您一個感受std::function<>
/boost::function<>
通過其封裝任何類型的可調用對象的能力,也請參閱this Q&A on StackOverflow。
這取決於你正在尋找什麼樣的答案!當然,以上所有內容都可以簡化爲'cout << DoIt(12,「a」,「b」)<< endl;',但我想這不是你想要的。也就是說,在這裏沒有明顯的機會利用Boost特性,因爲你調用的是純函數指針,而不是函數對象等。 – 2013-03-10 14:30:32
它可以被改進,然後你可以使用任何成員函數或lambda表達式(如果你有C++ 11兼容編譯器),不僅是普通函數或靜態成員函數。當然,使用'boost :: bind'(或['std :: bind'](http://en.cppreference.com/w/cpp/utility/functional/bind)),你可以「綁定」任何數字在傳遞函數對象之前的參數。 – 2013-03-10 14:31:05
什麼是固定的,什麼可以改變?如果'PassPtr'和'DoIt'的簽名是固定的,那麼否,代碼就像它得到的那樣簡單。 – 2013-03-10 14:32:13