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!
}
そして、これがライブの例です。
備考:
std::function<>
C++03 を使用している場合はboost::function<>
、簡単に変更できます(実際、Boost.Function はインスピレーションを得て、後に標準 C++ ライブラリの一部になりました)。この場合、ヘッダーを含める代わりに、およびヘッダーを含める必要があります(後者は を使用する場合のみ)。std::bind<>
boost::bind<>
std::function<>
<functional>
boost/function.hpp
boost/bind.hpp
boost::bind
std::function<>
/boost::function<>
があらゆる種類の呼び出し可能なオブジェクトをカプセル化する能力を通じてあなたに与える力を感じさせるさらなる例については、この Q&A on StackOverflowも参照してください。