Das Programm ist so gut wie ich sehe.
Laut [temp.param]/8 hat der Vorlagenparameter tatsächlich den Typ const int*
, nicht const int[]
.
A non-type template-Parameter vom Typ „Array von T
“ oder „-Funktion zurückkehr T
“ wird eingestellt, vom Typ „Zeiger auf T
“ oder als „Zeiger T
funktioniert Rückkehr“ bzw. .
Nach [temp.arg.nontype]/1, können wir den Namen eines vollständigen Array-Objekt mit statischen Speicherdauer und externe Bindung als Argument für eine solche Template-Parameter verwendet werden:
ein Template-Argument für einen nicht-Typ, nicht Vorlage Template-Parameter wird einer der folgenden sein:
...
- ein const ant-Ausdruck (5.19), der die Adresse eines vollständigen Objekts mit statischer Speicherdauer und externer oder interner Verknüpfung oder einer Funktion mit externer oder interner Verknüpfung bezeichnet, einschließlich Funktion Vorlagen und Funktion Vorlage-ID, jedoch nicht-statische Klassenmitglieder, ausgedrückt (ohne Berücksichtigung Klammern) als &
ID-expression, wo die ID-expression der Name eines Objekts oder eine Funktion ist, mit der Ausnahme, dass die &
wenn der Name auf eine Funktion oder ein Array verweist weggelassen werden, und wird weggelassen wenn der entsprechende Vorlage-Parameter eine Referenz ist ...
arr
ist ein konstanter Ausdruck, trotz der Tatsache, dass MSVC denkt, dass es nicht ist. Es ist ein zentraler konstanter Ausdruck gemäß [expr.const]/2, da es keine verbotenen Auswertungen enthält und ein konstanter Ausdruck ist, da er auf ein Objekt mit statischer Speicherdauer ([expr.const]/4) zeigt.
Da der Vorlagenparameter auf ein Array mit statischer Speicherdauer verweist, sind die Grenzen des Arrays zum Zeitpunkt der Vorlageninstanziierung bekannt. Es kann daher verifizieren, dass der Zugriff auf arr[0]
ein zulässiger Kernkonstantenausdruck ist, da er wohldefiniertes Verhalten aufweist und in die Kategorie der erlaubten lvalue-to-rvalue-Konvertierungen in [expr.const]/2:
... ein nichtflüchtiges glvalue von integralem oder Aufzählungstyp, der mit einer vorangehenden Initialisierung zu einem nichtflüchtigen const Objekt bezieht, mit einem konstanten Ausdruck initialisiert
Für der Datensatz akzeptiert auch Clang diesen Code. – jwimberley
Was sagt MSVC, wenn Sie 'arr []' durch 'arr [1]' ersetzen? – jwimberley
@jwimberley Es ändert nichts. –