使用指针模板参数

cos*_*cos 6 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 
}
Run Code Online (Sandbox Code Playgroud)

如何实例化此模板?

我可以做这个:

Port port;
int main() {
    PortWrapper<&port> port1;
}
Run Code Online (Sandbox Code Playgroud)

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

Rei*_*ica 2

你不能按原样,因为指针类型的非类型模板参数只能是空指针表达式或对象地址,而从整数的转换都不是这些。

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

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

public:
  PortWrapper() {
    port()->reg1 = 1;
    port()->reg2 = 2;
  }
};
Run Code Online (Sandbox Code Playgroud)

请注意,在评论中,@KonradRudolph 质疑这是否严格遵循函数规则constexpr,而且很可能没有。然而,即使constexpr从上面省略,任何像样的编译器都会内联 的调用port(),有效地导致编译时评估。