gpt4 book ai didi

c++ - 注册为模板参数

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:43:18 25 4
gpt4 key购买 nike

我正在寻找一种使用 gcc 4.8.4 将嵌入式设备寄存器传递给 C++ 模板的方法。在描述嵌入式设备的数据表中,寄存器的地址通常作为原始内存位置给出(例如 0x40008000)。

当我测试软件时,我想使用静态整数作为寄存器来查看寄存器值是否设置正确。

所以基本上一些设备外围设备的包装器归结为一个类,它的寄存器地址作为模板参数给出:

template < volatile std::uint32_t* Reg >
struct peripheral {};

测试工作正常:

std::uint32_t reg;
peripheral< &reg > mocked;

但是当我想用给定地址的固定数据表实例化模板时:

peripheral< reinterpret_cast< std::uint32_t* >( 0x40008000 ) > mocked;

gcc 提示:无法将模板参数 '1073774592u' 转换为 'volatile uint32_t* {aka volatile long unsigned int*}。 clang 对此没有提示。

如果我使用以整数形式给出的地址作为模板参数,我在测试期间使用模拟寄存器的地址实例化模板时会遇到问题:

template < std::intptr_t Reg >
struct peripheral {};

std::uint32_t reg;
peripheral< reinterpret_cast< std::intptr_t >( &reg ) > mocked;

这会导致错误:从常量表达式中的指针类型“uint32_t* {aka long unsigned int*}”转换为算术类型“intptr_t {aka int}”

我可以想到两种解决方案:

1) 使用指针作为模板参数,使用全局变量作为寄存器,并使用一些链接器脚本魔术固定寄存器的地址。

2) 使用特殊的寄存器类型,这些寄存器类型具有到外设模板的通用接口(interface),但用于测试和实际应用的实现却截然不同。

但我正在寻找一种更简单的方法来完成此任务。有什么想法、指示或评论吗?

最佳答案

在常量表达式中不允许执行 reinterpret_cast<>(编译器也会告诉您);另见 Constant expressions

我建议如下(另见 C++11 constexpr function's argument passed in template argument ):

#include <cstdint>
#include <cassert>

template<typename PtrT, PtrT Ptr>
struct peripheral
{
static void* const value;

template<typename T>
static T* as() noexcept
{ return static_cast<T*>(value); }
};

#define PERIPHERAL(addr) peripheral<decltype((addr)), (addr)>

std::uint32_t reg = 0;

int main() {
peripheral<std::uintptr_t, 0x42> mocked1;
peripheral<volatile std::uint32_t*, &reg> mocked2;
PERIPHERAL(0x42) mocked3;
PERIPHERAL(&reg) mocked4;
assert((mocked3.value == PERIPHERAL(0x42)::as<void*>()));
return 0;
}

关于c++ - 注册为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28604580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com