Nach welchen Regeln werden std::is_constructible
private Konstruktoren behandelt? Gegeben den folgenden Code:
#include <iostream>
class Class {
private:
Class() { }
};
template <typename T>
class Test {
public:
static void test() {
std::cout
//<< std::is_constructible<Class>::value
<< std::is_constructible<T>::value
<< std::endl;
}
};
int main() {
Test<Class>::test();
}
Dieser Druck 0
( ideone ) ist also T
nicht standardmäßig konstruierbar.
Ohne die kommentierte Zeile zu kommentieren, wird sie gedruckt 11
( ideone ), so dass sie plötzlichT
standardmäßig konstruierbar wurde.
Ich konnte Gründe finden, um beide Ergebnisse zu unterstützen, aber ich verstehe nicht, wie das Einfügen der kommentierten Zeile das Ergebnis der zweiten ändert. Ruft das irgendwie UB auf? Ist das ein Compiler-Fehler? Oder ist das std::is_constructible
wirklich inkonsistent?
c++
typetraits
Zennehoy
quelle
quelle
00
::value
Version in der Lage ist, die Ausgabe derjenigen zu ändern, die davor stehen: godbolt.org/z/zCy5xU Kommentieren Sie die kommentierte Zeile aus und alles wird 1: s in gcc.false
aber wenn die Funktionsvorlage nicht kommentiert ist, wird plötzlich Folgendes zurückgegebentrue
: godbolt.org/z/zqxdk2Antworten:
std::is_constructible
solltefalse
in diesem Szenario zurückkehren, da auf den Konstruktor nicht zugegriffen werden kann.Wie unter der Frage ausgeführt, wird das in der Frage beschriebene Verhalten durch einen Fehler in GCC / libstdc ++ verursacht. Der Fehler wird hier gemeldet und bezieht sich laut Bugzilla auf einen Zugriffssteuerungsfehler für Klassen in Vorlagenfunktionen , der seit einiger Zeit nicht mehr behoben wurde. Die Beziehung zwischen den beiden Fehlern stammt aus Jonathan Wakelys Bugzilla-Kommentar, der anscheinend zuerst die Verbindung zwischen den beiden Fehlern erkannt hat.
Dies wird auch dadurch impliziert, dass das Verhalten dieses Szenarios in GCC beim Löschen des Konstruktors korrekt wird, anstatt ihn privat zu machen:
was druckt
0
und00
jeweils. Dies ist die richtige Ausgabe (dieclang
im Szenario auch mit einem privaten Konstruktor korrekt meldet).Dies könnte die beobachtete Verhaltensänderung beim Kommentieren in der Zeile erklären , da innerhalb der Funktion in der Vorlagenstruktur die Zugriffsprüfung nicht funktioniert und gemeldet wird, dass auf den Konstruktor zugegriffen werden kann, wenn dies nicht der Fall ist. Wenn das Merkmal in der nächsten Zeile oder möglicherweise an einer völlig anderen Stelle erneut überprüft wird (wie dies hier der Fall ist ), wurde es bereits instanziiert und liefert somit die falsche Antwort.
quelle