假设我有一个模板类声明如下:
template< int *x > struct y { int *b; y() { b = x; }}
我确实需要模板参数作为常量内存地址 - 它是嵌入式代码。 如果我尝试像这样实例化它:(编译器是gcc 4.8.1 with -std = gnu ++ 11)
y< 1 > c;
我会收到错误“无法将模板参数'1'转换为'int *'”,这很好并且符合标准。我明白了。
我的问题是,转换为指针也不起作用:
y< (int *)1 > d;
y< reinterpret_cast<int *>(1) > e;
错误:无法将模板参数'1u'转换为'int *'
两种情况。这是为什么?模板参数已经转换,不是吗?
答案 0 :(得分:3)
根据C ++标准第14.3.2节
,这是不允许的非类型非模板模板参数的模板参数应为以下之一:
- 整数或枚举类型的整数常量表达式;或
- 非类型模板参数的名称;或
- 具有外部链接的对象或函数的地址,包括函数模板和函数模板ID,但不包括 非静态类成员,表示为&amp; id-expression其中&amp;是 如果名称引用函数或数组,或者如果是 相应的模板参数是一个参考; 或
- 指向成员的指针,如5.3.1
中所述
解决方案:
使用带有外部链接的变量作为模板参数:
template< int *x > struct y
{
int *b;
y() { b = x; }
};
extern int i; // Extern
static int j = 1; // Static
int z = 1; // Global
int main() {
y< &i > c1;
y< &j > c2;
y< &z > c3;
return 0;
}
直播示例here。
答案 1 :(得分:0)
“我不确定您的要求是什么,但我想您正在尝试为特定的硬件寄存器建模。这会满足您的需求吗?
#include <cstdint>
template< uintptr_t x > struct y {
int *const b;
y() : b(reinterpret_cast<int*>(x)) {}
};
int main() {
y< 42 > c;
return *c.b;
}