📌
UE5 C++ で関数テーブル作る[TMap]
TMap で関数テーブル作りたいときのメモ。
参考:
TFunctionを用いる
// 宣言
TMap<FString, TFunction<int32(int32, int32)>> arithmeticFunctions1; // TFunction 版
// 初期化
arithmeticFunctions1 = {
{"Add", [this](int a, int b) {return Add(a , b); }} ,
{"Sub", [this](int a, int b) {return Sub(a , b); }} ,
{"Mul", [this](int a, int b) {return Mul(a , b); }} ,
{"Div", [this](int a, int b) {return Div(a , b); }} ,
};
// 呼び出し例
// TFunctioin版の呼び出し
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Add"](1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Sub"](1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Mul"](1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Div"](1, 1));
// TFunctioin版の呼び出し(安全)
if (const TFunction<int32(int32, int32)>* func = arithmeticFunctions1.Find("Add")) {
UE_LOG(LogTemp, Log, TEXT("% d"), (*func)(1, 1));
}
関数ポインタを用いる
// 型定義
using arithmeticFunc = int32(AVRPawn::*) (int32, int32);
// 宣言(今回はstaticメンバを例)
static TMap<FString, arithmeticFunc> arithmeticFunctions2; // 関数ポインタ版
// 初期化
TMap<FString, AVRPawn::arithmeticFunc> AVRPawn::arithmeticFunctions2 = {
{"Add", &AVRPawn::Add},
{"Sub", &AVRPawn::Sub},
{"Mul", &AVRPawn::Mul},
{"Div", &AVRPawn::Div},
};
// 呼び出し例
// 関数ポインタ版の呼び出し
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Add"])(1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Sub"])(1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Mul"])(1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Div"])(1, 1));
// 関数ポインタ版の呼び出し(安全)
if (arithmeticFunc* arithmeticFunction = arithmeticFunctions2.Find("Add")) { // arithmeticFunction は関数ポインタへのポインタ
UE_LOG(LogTemp, Log, TEXT("%d"), (this->* * arithmeticFunction)(1, 1));
}
コード抜粋
//****************************************
// header
//****************************************
UCLASS()
class AVRPawn : public APawn
{
GENERATED_BODY()
private:
using arithmeticFunc = int32(AVRPawn::*) (int32, int32);
TMap<FString, TFunction<int32(int32, int32)>> arithmeticFunctions1; // TFunction 版
static TMap<FString, arithmeticFunc> arithmeticFunctions2; // 関数ポインタ版
public:
int32 Add(int32 a, int32 b);
int32 Sub(int32 a, int32 b);
int32 Mul(int32 a, int32 b);
int32 Div(int32 a, int32 b);
AVRPawn();
void BeginPlay() override;
};
//****************************************
// cpp
//****************************************
// 関数ポインタ版の初期化(static)
TMap<FString, AVRPawn::arithmeticFunc> AVRPawn::arithmeticFunctions2 = {
{"Add", &AVRPawn::Add},
{"Sub", &AVRPawn::Sub},
{"Mul", &AVRPawn::Mul},
{"Div", &AVRPawn::Div},
};
int32 AVRPawn::Add(int32 a, int32 b)
{
return a + b;
}
int32 AVRPawn::Sub(int32 a, int32 b)
{
return a - b;
}
int32 AVRPawn::Mul(int32 a, int32 b)
{
return a * b;
}
int32 AVRPawn::Div(int32 a, int32 b)
{
return b!=0 ? a/b: 0;
}
AVRPawn::AVRPawn()
{
// TFunction版の初期化
arithmeticFunctions1 = {
{"Add", [this](int a, int b) {return Add(a , b); }} ,
{"Sub", [this](int a, int b) {return Sub(a , b); }} ,
{"Mul", [this](int a, int b) {return Mul(a , b); }} ,
{"Div", [this](int a, int b) {return Div(a , b); }} ,
};
}
void AVRPawn::BeginPlay()
{
// TFunctioin版の呼び出し
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Add"](1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Sub"](1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Mul"](1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), arithmeticFunctions1["Div"](1, 1));
// TFunctioin版の呼び出し(安全)
if (const TFunction<int32(int32, int32)>* func = arithmeticFunctions1.Find("Add")) {
UE_LOG(LogTemp, Log, TEXT("% d"), (*func)(1, 1));
}
// 関数ポインタ版の呼び出し
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Add"])(1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Sub"])(1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Mul"])(1, 1));
UE_LOG(LogTemp, Log, TEXT("% d"), (this->*arithmeticFunctions2["Div"])(1, 1));
// 関数ポインタ版の呼び出し(安全)
if (arithmeticFunc* arithmeticFunction = arithmeticFunctions2.Find("Add")) {
// arithmeticFunction は関数ポインタへのポインタ
UE_LOG(LogTemp, Log, TEXT("%d"), (this->**arithmeticFunction)(1, 1));
}
}
Discussion