[英]How can I use static polymorphism to convert between int and pointer types?
我有这段代码:
#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。 我究竟做错了什么?
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> 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); }
当您的程序“崩溃”时,您应该在调试器中运行它。 您已经非常清楚地看到堆栈溢出,因为数百个堆栈帧都会显示相同的递归调用。
这个功能
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 或 std::intptr_t ......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.