【问题标题】:"could not convert template argument" error for pointer parameters even with cast即使使用强制转换,指针参数的“无法转换模板参数”错误
【发布时间】:2014-06-27 01:56:28
【问题描述】:

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

template< int *x > struct y { int *b; y() { b = x; }}

我确实需要模板参数是一个常量内存地址——它是一个嵌入式代码。 如果我尝试像这样实例化它:(编译器是 gcc 4.8.1 和 -std=gnu++11)

y< 1 > c;   

我会收到一个错误“无法将模板参数 '1' 转换为 'int*'”,这很好,符合标准。我明白了。

我的问题是转换为指针也不起作用:

y< (int *)1 > d;
y< reinterpret_cast<int *>(1) > e;

错误:无法将模板参数“1u”转换为“int*”

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

【问题讨论】:

    标签: c++ templates pointers


    【解决方案1】:

    根据 C++ 标准第 §14.3.2 节,这是不允许的

    非类型、非模板模板参数的模板参数应为以下之一:

    • 整数或枚举类型的整数常量表达式;或
    • 非类型模板参数的名称;或
    • 具有外部链接的对象或函数的地址,包括函数模板和函数模板ID,但不包括 非静态类成员,表示为 & id-expression 其中 & 是 如果名称引用函数或数组,或者如果 对应的模板参数是参考; 或
    • 指向成员的指针,如 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

    【讨论】:

      【解决方案2】:

      我不确定您的具体要求是什么,但我想您正在尝试对特定的硬件寄存器进行建模。这能满足您的需求吗?

      #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;  
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-02
        • 1970-01-01
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-18
        相关资源
        最近更新 更多