我有以下代码:
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)
但那不是我需要的.我需要将端口映射到预定义的常量地址.
你不能按原样,因为指针类型的非类型模板参数只能是空指针表达式或对象地址,而从整数的转换都不是这些。
您可以稍微重新设计模板:
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(),有效地导致编译时评估。