如何定义NAMEOF宏将成员函数指针转换为函数名字符串?
实现NAMEOF宏提取成员函数名(适配Unreal的TCHAR*需求)
要实现NAMEOF(&Whatever::FunctionName)转换为TEXT("FunctionName"),核心是从成员函数指针的字符串表示中提取出函数名部分,同时适配Unreal的TCHAR类型。以下是可行的实现方案:
方案:结合constexpr函数的宏定义
这种方法利用编译时函数处理字符串截取,既安全又高效,完全符合编译期常量的要求。
1. 定义编译时字符串处理函数
先写一个constexpr函数,在编译阶段遍历成员函数指针的字符串表示,找到最后一组::并返回其后的函数名:
#include <tchar.h> constexpr const TCHAR* ExtractMemberFuncName(const TCHAR* FullStr) { const TCHAR* LastDoubleColon = nullptr; while (*FullStr != TEXT('\0')) { // 匹配连续的两个冒号 if (*FullStr == TEXT(':') && *(FullStr + 1) == TEXT(':')) { LastDoubleColon = FullStr + 2; // 跳过::,指向函数名起始位置 } ++FullStr; } // 容错处理:如果没找到::,返回原字符串(避免非法输入崩溃) return LastDoubleColon ? LastDoubleColon : FullStr; }
2. 定义NAMEOF宏
通过宏将成员函数指针转换为字符串,再传递给上面的编译时函数:
#define NAMEOF(MemberFuncPtr) ExtractMemberFuncName(TEXT(#MemberFuncPtr))
3. 使用示例
直接替换原来的字符串字面量调用:
// 原来的写法 ProgressFunction.BindUFunction(this, "HandleProgress"); // 替换后的写法 ProgressFunction.BindUFunction(this, NAMEOF(&MyActor::HandleProgress));
关键原理说明
#MemberFuncPtr:预处理器将&MyActor::HandleProgress转换为C风格字符串字面量"&MyActor::HandleProgress"TEXT():将字符串转换为Unreal标准的TCHAR宽字符类型ExtractMemberFuncName:编译时遍历字符串,定位到最后一组::的位置,返回其后的函数名字符串指针,结果是编译期常量,完全满足BindUFunction对TCHAR*参数的要求
注意事项
- 确保宏的参数是
&类名::成员函数名格式的成员函数指针,传入普通函数指针或其他类型会导致提取结果不符合预期 - 如果Unreal的
BindUFunction严格要求非const的TCHAR*,可以在宏中添加const_cast<TCHAR*>,但不建议随意丢弃const属性,优先确认API是否兼容const参数
内容的提问来源于stack exchange,提问作者D G
相关产品推荐
相关产品推荐

