使用绝对指针地址作为模板参数 [英] using an absolute pointer address as a template argument

查看:93
本文介绍了使用绝对指针地址作为模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板类,它将foo *指针作为其第一个模板参数.我想使用位于绝对地址的foo实例化其中之一,如下所示:

I have a template class which takes as its first template argument a foo * pointer. I'd like to instantiate one of these with a foo located at an absolute address, like so:

class foo
{
    int baz;
};

template<foo *f> class bar
{
public:
    bar() {}
    void update() { /* ... */ }
};

// ....

#define FOO_ADDR ((foo *)0x80103400)
#define FOO_NULL ((foo *)0)

foo testFoo;

bar<FOO_ADDR> myFoo;        // fails with non-integral argument
bar<FOO_NULL> huh;          // compiles, I was surprised by this
bar<&testFoo> test;         // compiles as expected (but not useful)

有人知道是否有可能不借助链接器并通过外部链接定义FOO_ADDR?

Does anyone know if it's possible without resorting to the linker and getting FOO_ADDR to be defined with external linkage?

这与Keil ARM C/C ++编译器版本V5.06更新1(内部版本61)一起,我尝试切换为C ++ 11模式,但是(除了在系统头文件中引发大量新错误之外)它并没有改变行为.

This is with the Keil ARM C/C++ Compiler version V5.06 update 1 (build 61), I've tried switching on C++11 mode but (apart from throwing a load of new errors in the system headers) it didn't change the behaviour.

更新:这是使用int强制类型转换的建议解决方案(这次使用实际代码)

Update: here's the proposed solution (with the real code this time) using int casts

template<uint32 PORT, uint32 BIT, uint32 RATE> class LedToggle
{
    uint32 mTicks;
    uint32 mSetReset;

    public:

    LedToggle()
    {
        mTicks = 0;
        mSetReset = 1 << BIT;
    }

    void Update()
    {
        uint32 mask = ((mTicks++ & RATE) - 1) >> 31;
        ((GPIO_TypeDef *)PORT)->BSRR = mSetReset & mask;
        mSetReset ^= ((1 << BIT) | (1 << (BIT + 16))) & mask;
    }
};

LedToggle<(uint32)GPIOC, 13, 1023> led;

这很丑陋,但确实有效.我想知道是否有人可以对此进行改进?

It's pretty ugly, but it does work. I'd be interested to hear if anyone can improve on it?

推荐答案

声明bar<(foo*)0x80103400> myFoo;格式错误,因为非类型模板参数必须是[temp.arg.nontype]中的常量表达式:

The declaration bar<(foo*)0x80103400> myFoo; is ill-formed because non-type template arguments must be a constant expression, from [temp.arg.nontype]:

非类型 template-parameter template-argument 应该是 template-parameter .

您传递的参数不是来自[expr.const]:

And the argument you are passing is not, from [expr.const]:

条件表达式e是核心常数表达式,除非按照e的规则对e求值. 抽象机(1.9),将评估以下表达式之一:
— [...]
-a reinterpret_cast(5.2.10);
— [...]

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
— [...]
— a reinterpret_cast (5.2.10);
— [...]

声明bar<(foo*)0> huh之所以有效,是因为它不涉及强制转换,它只是类型为foo*的空指针(0是特殊的),因此它是有效的常量表达式.

The declaration bar<(foo*)0> huh works since it does not involve a cast, it's simply a null pointer of type foo* (0 is special) and so it is a valid constant expression.

您可以直接将地址作为模板非类型参数传递:

You could instead simply pass in the address as a template non-type parameter:

template <uintptr_t address>
struct bar { ... };

bar<0x8013400> myFooWorks;

那是可行的.

这篇关于使用绝对指针地址作为模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆