Cha*_*eck 9 c++ templates pointers
我有一个模板类,它将第一个模板参数作为foo*指针.我想用一个位于绝对地址的foo来实例化其中一个,如下所示:
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)
Run Code Online (Sandbox Code Playgroud)
有没有人知道是否可以不借助链接器并使用外部链接定义FOO_ADDR?
这是使用Keil ARM C/C++编译器版本V5.06更新1(版本61),我尝试切换C++ 11模式但是(除了在系统头文件中抛出大量新错误)它没有'改变行为.
更新:这是使用int强制转换的建议解决方案(这次使用真实代码)
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;
Run Code Online (Sandbox Code Playgroud)
这很丑陋,但确实有效.我有兴趣听听是否有人可以改进它?
声明bar<(foo*)0x80103400> myFoo;
格式不正确,因为非类型模板参数必须是[temp.arg.nontype]的常量表达式:
甲模板参数的用于非类型模板参数应为的类型的一个转换后的常量表达式(5.20)模板参数.
你传递的论点不是,来自[expr.const]:
条件表达式e是核心常量表达式,除非按照抽象机器(1.9)的规则评估e将评估以下表达式之一:
- [...]
- areinterpret_cast
(5.2.10);
- [...]
声明bar<(foo*)0> huh
有效,因为它不涉及强制转换,它只是一个类型的空指针foo*
(0
特殊),因此它是一个有效的常量表达式.
您可以简单地将地址作为模板非类型参数传递:
template <uintptr_t address>
struct bar { ... };
bar<0x8013400> myFooWorks;
Run Code Online (Sandbox Code Playgroud)
这是可行的.
面对同样的问题(在 STM32 上),作为一种解决方法,我找到了函数指针模板参数,如下所示:
template<GPIO_TypeDef* PORT(), uint32 BIT, uint32 RATE>
class LedToggle
{
public:
void Update()
{
// ...
PORT()->BSRR = mSetReset & mask;
// ...
}
};
constexpr GPIO_TypeDef* Port_C() {
return PORTC;
}
LedToggle<Port_C, 13, 1023> led;
Run Code Online (Sandbox Code Playgroud)
请注意,我们使用函数指针作为模板参数,指向返回所需实际指针的函数。在该函数内部允许强制转换;并且由于函数被声明constexpr
,编译器可能(应该)优化掉实际的函数调用并像文字一样使用函数的返回值。
归档时间: |
|
查看次数: |
1329 次 |
最近记录: |