我试图将一个内存地址分配给一个指针,但是无法使其编译。 该地址是一个内存映射的硬件寄存器。
#include <memory>
template<void* Address>
struct ClassAImpl {
uint64_t* Register = reinterpret_cast<uint64_t*>(Address);
};
uint8_t arrA[10] = { 1, 2, 3, 4 };
using ClassA1 = ClassAImpl<(void*)&arrA>; // error: the address of the 'void' subobject of 'arrA' is not a valid template argument
using ClassA2 = ClassAImpl<0x8767876787678767>; // error: could not convert template argument '9756915996444559207' from 'long unsigned int' to 'void*'
template<uint64_t Address>
struct ClassBImpl {
uint64_t* Register = reinterpret_cast<uint64_t*>(Address);
};
uint8_t arrB[10] = { 1, 2, 3, 4 };
using ClassB1 = ClassBImpl<(void*)&arrB>; // error: conversion from 'void*' to 'long unsigned int' in a converted constant expression
using ClassB2 = ClassBImpl<0x8767876787678767>; // This compiles.
我想同时使用指向缓冲区的指针和ClassA2使用固定地址。
我正在使用Gcc 8.2编译C ++
答案 0 :(得分:0)
我不知道您要达到什么目的,但是您陷入非类型模板参数的奇怪行为。非类型模板参数不能用临时实例化。来自https://en.cppreference.com/w/cpp/language/template_parameters:
“对于指向对象的指针,模板参数必须指定 具有静态存储持续时间的完整对象的地址和 链接(内部或外部),或一个常量表达式 计算为适当的空指针或std :: nullptr_t值。”
using ClassA1 = ClassAImpl<(void*)&arrA>; - temporary
using ClassA2 = ClassAImpl<0x8767876787678767>; - template argument is constant expression, template parameter is pointer to void, doesn't make any sense
using ClassB1 = ClassBImpl<(void*)&arrB>; - temporary
using ClassB2 = ClassBImpl<0x8767876787678767>; - constant expression which can be used as template parameter uint64_t
答案 1 :(得分:0)
也许您想要类似的东西:
#include <stdint.h>
uint64_t (&hw_regs)[10] = *reinterpret_cast<uint64_t(*)[10]>(0xdeadbeefUL);
uint64_t &hw_reg0 = hw_regs[0];
根据需要制作引用的对象volatile
。如果您询问要用脚射击自己的子弹的正确口径,那么您就会知道自己在做什么。标准的[expr.reinterpret.cast]部分允许进行此强制转换,但是当然,引用不是安全地得出的。