2014-05-15 6 views
5

ich den folgenden Code haben:Mit Zeiger Template-Parameter

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 
} 

Wie kann ich diese Vorlage instanziiert?

Ich kann dies tun:

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

Aber das ist nicht das, was ich brauche. Ich brauche einen Port, der auf eine vordefinierte konstante Adresse abgebildet wird.

Antwort

2

Sie können nicht wie sie ist, da nicht type Template-Argumente vom Zeigertyp nur Nullzeigerausdrücke oder Adressen von Objekten sein können, und eine Konvertierung von einem Integer ist keines davon.

Sie könnten die Vorlage leicht Redesign:

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

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

Beachten Sie, dass in den Kommentaren, ob @KonradRudolph Streitigkeiten dies strikt an die Regeln für eine constexpr Funktion folgt, und es ist durchaus möglich, es funktioniert nicht. Dennoch, auch wenn constexpr aus dem oben genannten weggelassen wird, wird jeder ordentliche Compiler den Aufruf von port() inline, was effektiv zu Kompilierungszeit Auswertung führt.

+0

+1: Genau was ich tun würde. (Immer ein guter Grund; P) –

+1

Seit wann kann ein 'reinterpret_cast' ein' constexpr' sein? Ist das C++ 14? (Ich meine, sicher, das wird kompiliert, aber das Ergebnis wird * nicht * zur Kompilierzeit ausgewertet) –

+0

@KonradRudolph Sie haben recht, es braucht einen C-Style-Cast. Geändert. Ich bin mit VS2010 festgefahren, also bin ich mit den constexpr-Regeln nicht auf Hochtouren. Und ich würde sagen, dass unabhängig davon, ob es der Definition von "constexpr" entspricht, jeder vernünftige Compiler das in der Kompilierzeit auswerten wird. – Angew