使用指针模板参数

时间:2014-05-15 10:12:44

标签: c++ templates

我有以下代码:

struct Port {
    int reg1;
    int reg2;
};

#define PORT1 ((Port *) 0x00010000); // absolutely compile-time constants
#define PORT2 ((Port *) 0x00020000);

template <Port * port>
class PortWrapper {
public:
    PortWrapper() {
        port->reg1 = 1;
        port->reg2 = 2;
    }
};

constexpr static const Port * const port1c = PORT1;

int main(int argc, char* argv[]) {
    PortWrapper<PORT1> port1; //Compiler says: error: could not convert template argument '65536u' to 'Port*'
    PortWrapper<port1c> port1; //Compiler says: error: 'port1c' is not a valid template argument because 'port1c' is a variable, not the address of a variable 
}

如何实例化此模板?

我可以这样做:

Port port;
int main() {
    PortWrapper<&port> port1;
}

但这不是我需要的。我需要将端口映射到预定义的常量地址。

1 个答案:

答案 0 :(得分:2)

您可以按原样,因为指针类型的非类型模板参数只能是空指针表达式或对象的地址,并且从整数转换不是那些。

您可以稍微重新设计模板:

template <uintptr_t portAddr>
class PortWrapper {
private:
  static constexpr Port* port() { return (Port*)portAddr; }

public:
  PortWrapper() {
    port()->reg1 = 1;
    port()->reg2 = 2;
  }
};

请注意,在评论中,@ KonradRudolph对这是否严格遵循constexpr函数的规则进行了争议,并且它很可能不会。尽管如此,即使从上面省略constexpr,任何体面的编译器都会内联port()的调用,从而有效地进行编译时评估。