如何在宏中获取智能指针的类型?
How to get type of smart pointer in macros?
这行太长了:
btnNickname = TWeakObjectPtr<UButton>(Cast<UButton>(WidgetTree->FindWidget(FName(STRINGIFY(btnNickname))));
对于定义为的变量:
TWeakObjectPtr<UButton> btnNickname;
我想创建宏来减少代码:
FIND_WIDGET(btnNickname);
有什么办法吗?
我现在使用这个代码:
#define FIND_WIDGET(TYPE, NAME) NAME = TWeakObjectPtr<TYPE>(Cast<TYPE>(WidgetTree->FindWidget(FName(STRINGIFY(NAME)))))
但是宏有两个参数。我可以从 TWeakObjectPtr
变量中获取指针类型吗?
decltype
可以给我变量类型,但不能给我指针数据类型。
物质:
#define FIND_WIDGET(NAME) NAME = TWeakObjectPtr<decltype(*NAME)>(Cast<decltype(*NAME)>(WidgetTree->FindWidget(FName(STRINGIFY(NAME)))))
但这行不通。
P.S。 TWeakObjectPtr
是Unreal Engine中使用的智能指针 4.
大概是这样的:
template <typename T>
TWeakObjectPtr<T> FindWidgetHelper(
TWidgetTree* tree, const char* name, TWeakObjectPtr<T> widget) {
return TWeakObjectPtr<T>(Cast<T>(tree->FindWidget(FName(name))));
}
#define FIND_WIDGET(NAME) \
NAME = FindWidgetHelper(WidgetTree, STRINGIFY(NAME), NAME)
根据口味调整。我对Unreal Engine完全不熟悉,不得不猜测各种事物的类型。
从智能指针中提取类型的一种简单方法可能是(未经测试):
template<typename T> struct Untweaker;
template<typename T> struct Untweaker<TWeakObjectPtr<T>> {
using type = T;
}
template<typename T> using Untweak = typename Untweaker<T>::type;
然后你可以使用Untweak<decltype(variable)>
来提取实际类型。
您可以 TWeakObjectPtr::GetEvenIfUnreachable
找到给定 TWeakObjectPtr
的类型,如下所示:
remove_pointer_t<decltype(btnNickname.GetEvenIfUnreachable())>
所以基本上只需将其插入您现有的宏即可:
#define FIND_WIDGET(NAME) NAME = TWeakObjectPtr<remove_pointer_t<decltype(NAME.GetEvenIfUnreachable())>>(Cast<remover_pointer_t<decltype(NAME.GetEvenIfUnreachable())>>(WidgetTree->FindWidget(FName(STRINGIFY(NAME)))))
完全公开我不得不询问如何获得这些类型:
我认为它不起作用的原因是 decltype(*NAME)
是引用类型,因此您需要删除引用:
std::remove_reference_t<decltype(*NAME)>
或者您可以这样做:
std::remove_pointer_t<decltype(NAME.operator->())>
但无论如何您都不应该使用宏。宏的气味和 parents 会指着你并告诉他们 children 不要靠近使用宏的坏人。编写 C++,而不是宏。
编译器可以很容易地推导出object的类型:
template<typename T>
inline void
find_widget(TWeakObjectPtr<T>& t, const char* name)
{
t = TWeakObjectPtr<T>(Cast<T>(WidgetTree->FindWidget(FName(name))));
}
然后:
find_widget(foo, STRINGIFY(foo));
这更灵活,因为您还可以:
find_widget(foo, "something else");
N.B。 find_widget
对于修改参数的东西来说似乎不是一个很好的名字。
这行太长了:
btnNickname = TWeakObjectPtr<UButton>(Cast<UButton>(WidgetTree->FindWidget(FName(STRINGIFY(btnNickname))));
对于定义为的变量:
TWeakObjectPtr<UButton> btnNickname;
我想创建宏来减少代码:
FIND_WIDGET(btnNickname);
有什么办法吗?
我现在使用这个代码:
#define FIND_WIDGET(TYPE, NAME) NAME = TWeakObjectPtr<TYPE>(Cast<TYPE>(WidgetTree->FindWidget(FName(STRINGIFY(NAME)))))
但是宏有两个参数。我可以从 TWeakObjectPtr
变量中获取指针类型吗?
decltype
可以给我变量类型,但不能给我指针数据类型。
物质:
#define FIND_WIDGET(NAME) NAME = TWeakObjectPtr<decltype(*NAME)>(Cast<decltype(*NAME)>(WidgetTree->FindWidget(FName(STRINGIFY(NAME)))))
但这行不通。
P.S。 TWeakObjectPtr
是Unreal Engine中使用的智能指针 4.
大概是这样的:
template <typename T>
TWeakObjectPtr<T> FindWidgetHelper(
TWidgetTree* tree, const char* name, TWeakObjectPtr<T> widget) {
return TWeakObjectPtr<T>(Cast<T>(tree->FindWidget(FName(name))));
}
#define FIND_WIDGET(NAME) \
NAME = FindWidgetHelper(WidgetTree, STRINGIFY(NAME), NAME)
根据口味调整。我对Unreal Engine完全不熟悉,不得不猜测各种事物的类型。
从智能指针中提取类型的一种简单方法可能是(未经测试):
template<typename T> struct Untweaker;
template<typename T> struct Untweaker<TWeakObjectPtr<T>> {
using type = T;
}
template<typename T> using Untweak = typename Untweaker<T>::type;
然后你可以使用Untweak<decltype(variable)>
来提取实际类型。
您可以 TWeakObjectPtr::GetEvenIfUnreachable
找到给定 TWeakObjectPtr
的类型,如下所示:
remove_pointer_t<decltype(btnNickname.GetEvenIfUnreachable())>
所以基本上只需将其插入您现有的宏即可:
#define FIND_WIDGET(NAME) NAME = TWeakObjectPtr<remove_pointer_t<decltype(NAME.GetEvenIfUnreachable())>>(Cast<remover_pointer_t<decltype(NAME.GetEvenIfUnreachable())>>(WidgetTree->FindWidget(FName(STRINGIFY(NAME)))))
完全公开我不得不询问如何获得这些类型:
我认为它不起作用的原因是 decltype(*NAME)
是引用类型,因此您需要删除引用:
std::remove_reference_t<decltype(*NAME)>
或者您可以这样做:
std::remove_pointer_t<decltype(NAME.operator->())>
但无论如何您都不应该使用宏。宏的气味和 parents 会指着你并告诉他们 children 不要靠近使用宏的坏人。编写 C++,而不是宏。
编译器可以很容易地推导出object的类型:
template<typename T>
inline void
find_widget(TWeakObjectPtr<T>& t, const char* name)
{
t = TWeakObjectPtr<T>(Cast<T>(WidgetTree->FindWidget(FName(name))));
}
然后:
find_widget(foo, STRINGIFY(foo));
这更灵活,因为您还可以:
find_widget(foo, "something else");
N.B。 find_widget
对于修改参数的东西来说似乎不是一个很好的名字。