我有以下代码示例:
#include <iostream>
typedef struct MyStruct {
int member;
} crake;
#define GPIOA ( 0x40000000)
template <typename T, crake* Ptr>
struct MyTemplate {
void doSomething() {
Ptr->member = 42;
}
};
int main() {
crake* ptr = reinterpret_cast<crake*>(GPIOA);
MyTemplate<MyStruct, reinterpret_cast<crake*>(GPIOA)> instance;
instance.doSomething();
return 0;
}
我用C++20编译了它。有趣的是,我在行上得到了一个错误MyTemplate<MyStruct, reinterpret_cast<crake*>(GPIOA)> instance;
但不是在前面的一行,我做了同样的事情,即重新解释转换一个整数到一个指针。
确切的错误消息说:
"error: ‘reinterpret_cast’ from integer to pointer
29 | MyTemplate<MyStruct, reinterpret_cast<crake*>(GPIOA)> instance;"
我的目标是获取一个定义为常量值(使用#define
)的结构体的地址作为非类型模板参数。我知道这会崩溃,但实际上,地址后面有一个外围设备,向其写入是可以的。所以我假设,我需要使用一个常量变量,但我想避免这种情况。
1条答案
按热度按时间8wigbo561#
模板参数如下:
...必须是常量表达式。
reinterpret_cast
不能用于常量表达式。在这种情况下,允许它的问题在于,您创建了一个指向一个在编译时不存在的对象的指针,因此template参数在某种程度上没有意义。编译时存在的内存不同于运行时的内存。但是,您可以将地址作为模板参数传递,并在运行时执行转换:
与原始代码相比,这没有额外的开销,并且编译为:
参见live example on Compiler Explorer。