如何使用静态多态性在 int 和指针类型之间进行转换?
Posted
技术标签:
【中文标题】如何使用静态多态性在 int 和指针类型之间进行转换?【英文标题】:How can I use static polymorphism to convert between int and pointer types? 【发布时间】:2020-01-04 23:59:04 【问题描述】:我有这段代码:
#include <iostream>
template<class T> void* ToPtr(T t) return ToPtr((void*)t);
void* ToPtr(void* i) return i;
void* ToPtr(int i) return (void*)(long)(unsigned int)i;
template<class T> int ToInt(T t) return ToInt((void*)t);
int ToInt(void* i) return (int)(unsigned int)(long)i;
int ToInt(int i) return i;
struct MyClass
template<class T>
void* Find(T t) return ToPtr(t);
template<class T>
int FindInt(T t) return ToInt(t);
;
int main()
MyClass myClass;
int myInt = 1;
std::cout << &myClass << std::endl;
std::cout << myInt << std::endl;
std::cout << myClass.Find(&myClass) << std::endl;
std::cout << myClass.Find(myInt) << std::endl;
std::cout << myClass.FindInt(&myClass) << std::endl;
std::cout << myClass.FindInt(myInt) << std::endl;
程序在第一次调用 Find() 时崩溃,但我不知道为什么。我正在使用 GCC 6.2.0,它仅符合 C++14,否则我会使用 constexpr。我做错了什么?
【问题讨论】:
您可能应该在这里解释您要做什么。连续进行 3 次 c 样式转换的原因是什么?某种促销技巧? 你的目标是什么? 什么样的“崩溃”?实际发生了什么? 您的模板ToPtr
将无法找到在它之后声明的函数。您正在递归调用模板版本到无穷大。
我的应用程序有一些遗留代码,它们同时接受 int 和 void* 并将它们存储在 void* 数据结构中。现在,每个版本的函数只复制了一堆函数。我正在尝试通过使用模板来生成变体来减少列表。
【参考方案1】:
template<class T> void* ToPtr(T t) return ToPtr((void*)t);
这会调用自己。永远。
由于非模板比模板更受欢迎,这很容易解决:您只需将非模板放在 first 以便它们在上述重载的范围内:
void* ToPtr(void* i) return i;
void* ToPtr(int i) return (void*)(long)(unsigned int)i;
template<class T> void* ToPtr(T t) return ToPtr((void*)t);
int ToInt(void* i) return (int)(unsigned int)(long)i;
int ToInt(int i) return i;
template<class T> int ToInt(T t) return ToInt((void*)t);
(live demo)
当您的程序“崩溃”时,您应该在调试器中运行它。您会非常清楚地看到堆栈溢出,因为数百个堆栈帧都会显示相同的递归调用。
【讨论】:
【参考方案2】:这个函数
template<class T> void* ToPtr(T t) return ToPtr((void*)t);
无限期地调用自己……
ToPtr
不是此函数模板中的依赖名称(因为转换为 void*
绝不是依赖类型的表达式 [temp.dep.expr]/3),因此,在函数模板的定义点查找它,而不是在实例化点。因为ToPtr
的其他重载都没有在定义点声明,所以函数模板最终会调用自己。确保 ToPtr
的所有重载都在函数模板的定义之前声明...
除此之外,您真的不应该将指针转换为unsigned int
或int
,因为这些类型不能保证足够大以实际表示指针值。如果您确实必须这样做,请使用std::uintptr_t or std::intptr_t...
【讨论】:
以上是关于如何使用静态多态性在 int 和指针类型之间进行转换?的主要内容,如果未能解决你的问题,请参考以下文章