即使使用强制转换,“也无法转换模板参数”错误的指针参数

时间:2014-06-27 01:56:28

标签: c++ templates pointers

假设我有一个模板类声明如下:

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 *'

两种情况。这是为什么?模板参数已经转换,不是吗?

2 个答案:

答案 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;  
}