Bei der Beantwortung dieser Frage habe ich den folgenden Code mit gcc ( Code kompiliert ) und klingeln ( Code abgelehnt ) ):
%Vor% Ich bin mir nicht sicher, welcher Compiler richtig ist, obwohl ich denke, dass die constexpr-Initialisierung von Test::f
in Ordnung ist. Die Fehler-Ausgänge sind:
BEARBEITEN : Für das "Warum" siehe DyPs Frage .
14.3.2 Template-Nicht-Typ-Argumente [temp.arg.nontype]
Ein Template-Argument für einen Nicht-Template-Template-Template-Template-Template ist:
[...]
- ein konstanter Ausdruck (5.19), der die Adresse eines Objekts mit statischem Speicher & gt; Dauer und externe oder interne Verknüpfung oder eine Funktion mit externer oder interner Verknüpfung , einschließlich Funktionsvorlagen und Funktionsschablonen-IDs, jedoch nicht-statische Klassenmitglieder ausgenommen, ausgedrückt (ohne Klammern) als & amp; ID-Ausdruck , außer dass der & amp; kann weggelassen werden, wenn der Name auf eine Funktion oder ein Array verweist und ausgelassen wird, wenn der entsprechende Template-Parameter eine Referenz ist; [...]
(n3485, Hervorhebung von mir)
Ich weiß nicht genau, warum es begrenzt war, aber ich denke, es könnte damit zusammenhängen, dass die Funktionsadresse zur Kompilierzeit nicht verfügbar ist (es könnte einen Ersatz für die Template-Instanziierung geben).
Bearbeiten: Verbesserte Antwort aufgrund einer Folgefrage (Kommentar) von Synxis
%Vor% ^ das ist wohlgeformt; Sie können die Adresse einer Funktion verwenden, um ein Objekt constexpr
zu initialisieren.
Das Problem besteht darin, dass es ausdrücklich verboten ist, Zeiger als nicht typisierte Vorlagenargumente außer dem Formular &identifier
zu verwenden:
Tags und Links c++ c++11 constexpr static function-pointers