これはおそらく哲学的な質問ですが、次の問題に遭遇しました。
std::function を定義し、それを正しく初期化しないと、アプリケーションは次のようにクラッシュします。
typedef std::function<void(void)> MyFunctionType;
MyFunctionType myFunction;
myFunction();
関数が引数として渡される場合、次のようになります。
void DoSomething (MyFunctionType myFunction)
{
myFunction();
}
もちろん、それもクラッシュします。これは、次のようなチェック コードを追加する必要があることを意味します。
void DoSomething (MyFunctionType myFunction)
{
if (!myFunction) return;
myFunction();
}
これらのチェックを要求すると、すべてのポインター引数を明示的にチェックする必要もあった古い C 時代にフラッシュバックします。
void DoSomething (Car *car, Person *person)
{
if (!car) return; // In real applications, this would be an assert of course
if (!person) return; // In real applications, this would be an assert of course
...
}
幸いなことに、C++ で参照を使用できるため、これらのチェックを書くことができません (呼び出し元が nullptr の内容を関数に渡さなかったと仮定すると:
void DoSomething (Car &car, Person &person)
{
// I can assume that car and person are valid
}
では、なぜ std::function インスタンスにデフォルトのコンストラクターがあるのでしょうか? デフォルトのコンストラクターがなければ、関数の他の通常の引数と同様に、チェックを追加する必要はありません。また、「オプションの」 std::function を渡したい「まれな」ケースでは、ポインタを渡すこともできます (または boost::optional を使用します)。