はじめに
本記事は UE にある TFunction系のクラスについての情報や使用するにあたって意識すべき点を簡単にまとめた物になります。
対象読者はプログラマーを想定しており、関数オブジェクトなどいくつかの用語説明は省くことをご了承頂いた上で読み進めてもらえると幸いです。
なにか間違ってたらコメントください
TFunction
std::function のUEC++バージョン
関数オブジェクトなど呼び出し可能な物を保持できます。
コールバック等の用途でこれが関数の引数として使用されることもありますが、この時にコピーコストが気になる場合は後述するTFunctionRef に出来ないかも検討してみてください。
記述例:
// 変数
TFunction<bool(int32)> ReturnFalse = [](int32 a)
{
return false;
};
// 引数
void Func(TFunction<bool(void)> Predicate)
{
if (Predicate())
{
std::cout << "True";
}
std::cout << "False";
}
TFunctionRef
関数オブジェクトなど呼び出し可能な物の参照を保持します。
TFunctionとは違い参照を保持するため、TFunctionと比べてコピーコストを気にしなくてもいいことが利点ですが、下記のような場合だとラムダのスコープが抜けて破棄されるため、不正アクセスとなります。
TFunctionRef<bool(void)> f = []{ return false; };
f(); // この時には↑は破棄されているため、不正アクセスとなる
/*
@note TFunctionRefクラスコメント一部抜粋
A class which represents a reference to something callable.
The important part here is reference - if you bind it to a lambda and the lambda
goes out of scope, you will be left with an invalid reference.
google翻訳:
呼び出し可能なものへの参照を表すクラス。
ここで重要な部分は参照です。これをラムダにバインドし、ラムダがスコープ外になると、
無効な参照が残ります。
*/
ラムダ式を変数へと格納したい場合は下記のように、autoやTFunctionを使用してください。
auto Func = []{ return false; };
TFunction<bool(void)> Func2 = []{ return false; };
TUniqueFunction
基本的にはTFunctionと同等ですが、所有権が唯一になるように振舞います。
そのため、基本的にはコピーが出来ず、MoveTempで所有権を移譲します。
TUniqueFunction<bool(void)> UniqueFunc = []{ return false; };
TFunction<bool(void)> a = UniqueFunc; // NG
TUniqueFunction<bool(void)> b = UniqueFunc; // NG
TUniqueFunction<bool(void)> c = MoveTemp(UniqueFunc); // OK