如何在 C++ 中创建任意类型的指针常量?
How can I create a any-type pointer constant in C++?
我想要一个可以分配给任何指针的整数常量。我打算使用这个特殊值来标记最近删除的指针(仅用于调试目的)。我想创建一个结构,然后使用处理每个可能的 LHS 指针和我的 RHS 自定义类型的模板覆盖赋值运算符 =。
但是,据我所知,除了作为成员之外,没有办法重载赋值运算符 = 的左侧。我想出了这个(非编译)代码,如果没有语言边界,它会产生预期的结果。
struct TPointerConst
{
TPointerConst(uint64 InValue) : Value(InValue) { }
template <typename TPtr>
friend TPtr& operator=(TPtr& Left, const TPointerConst& Right);
private:
uint64 Value;
};
template <typename TPtr>
TPtr& operator=(TPtr& Left, const TPointerConst& Right) {
return Left = (TPtr)Right.Value;
}
constexpr TPointerConst DELETED_PTR = 0xFADE404;
/* ... */
int* intPtr = DELETED_PTR;
float* fltPtr = DELETED_PTR;
我还考虑过将一个值强制转换为 nullptr_t(当我想到它时,这似乎真的很奇怪)只是为了满足编译器,但我怀疑你不能将任何内容强制转换为 nullptr_t。
我想尽可能地避免使用宏,但是如果我只为这个功能留下一个类似 const 的宏(比如好的,旧的 NULL),那也不会太糟糕。我的目标至少是 C++11,所以任何符合现代 C++ 的东西都会令人满意。
template<typename T> operator T*()
会有用:
struct TPointerConst{
TPointerConst(std::uintptr_t v) :value(v){};
template<typename T>
operator T*() const{
return reinterpret_cast<T*>(value);
}
private:
std::uintptr_t value;
};
int main(){
TPointerConst a = 0xCDCDCDCD;
int* b = a;
}
我设法通过重载转换运算符而不是赋值来处理这个问题。老实说,我认为那些不能成为模板,事实证明我错了。这是一个概念证明,我将向其添加静态断言以使其更安全。
struct TPointerConst
{
constexpr TPointerConst(uint64 InValue) noexcept : Value(InValue) { }
template <typename TPtr>
constexpr operator TPtr() const {
return (TPtr)Value;
}
private:
uint64 Value;
};
constexpr TPointerConst DELETED_PTR(0x001);
int main()
{
int* intPtr = DELETED_PTR;
float* fltPtr = DELETED_PTR;
cout << intPtr << endl << fltPtr;
}
我想要一个可以分配给任何指针的整数常量。我打算使用这个特殊值来标记最近删除的指针(仅用于调试目的)。我想创建一个结构,然后使用处理每个可能的 LHS 指针和我的 RHS 自定义类型的模板覆盖赋值运算符 =。
但是,据我所知,除了作为成员之外,没有办法重载赋值运算符 = 的左侧。我想出了这个(非编译)代码,如果没有语言边界,它会产生预期的结果。
struct TPointerConst
{
TPointerConst(uint64 InValue) : Value(InValue) { }
template <typename TPtr>
friend TPtr& operator=(TPtr& Left, const TPointerConst& Right);
private:
uint64 Value;
};
template <typename TPtr>
TPtr& operator=(TPtr& Left, const TPointerConst& Right) {
return Left = (TPtr)Right.Value;
}
constexpr TPointerConst DELETED_PTR = 0xFADE404;
/* ... */
int* intPtr = DELETED_PTR;
float* fltPtr = DELETED_PTR;
我还考虑过将一个值强制转换为 nullptr_t(当我想到它时,这似乎真的很奇怪)只是为了满足编译器,但我怀疑你不能将任何内容强制转换为 nullptr_t。
我想尽可能地避免使用宏,但是如果我只为这个功能留下一个类似 const 的宏(比如好的,旧的 NULL),那也不会太糟糕。我的目标至少是 C++11,所以任何符合现代 C++ 的东西都会令人满意。
template<typename T> operator T*()
会有用:
struct TPointerConst{
TPointerConst(std::uintptr_t v) :value(v){};
template<typename T>
operator T*() const{
return reinterpret_cast<T*>(value);
}
private:
std::uintptr_t value;
};
int main(){
TPointerConst a = 0xCDCDCDCD;
int* b = a;
}
我设法通过重载转换运算符而不是赋值来处理这个问题。老实说,我认为那些不能成为模板,事实证明我错了。这是一个概念证明,我将向其添加静态断言以使其更安全。
struct TPointerConst
{
constexpr TPointerConst(uint64 InValue) noexcept : Value(InValue) { }
template <typename TPtr>
constexpr operator TPtr() const {
return (TPtr)Value;
}
private:
uint64 Value;
};
constexpr TPointerConst DELETED_PTR(0x001);
int main()
{
int* intPtr = DELETED_PTR;
float* fltPtr = DELETED_PTR;
cout << intPtr << endl << fltPtr;
}