Quelles sont les règles de std::is_constructible
gestion des constructeurs privés? Étant donné le code suivant:
#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();
}
Cette affiche0
( ideone ), c'est à dire, T
n'est pas constructible par défaut.
Décommentant la ligne commentée, elle s'affiche11
( ideone ), si T
soudainement devenue par défaut constructible.
Je pourrais trouver un raisonnement pour soutenir les deux résultats, mais je ne comprends pas comment l'inclusion de la ligne commentée modifie le résultat de la seconde. Est-ce que cela appelle en quelque sorte UB? S'agit-il d'un bug du compilateur? Ou est-ce std::is_constructible
vraiment incohérent?
c++
typetraits
zennehoy
la source
la source
00
::value
version soit capable de changer la sortie de ceux qui la précèdent aussi: godbolt.org/z/zCy5xU Décommentez la ligne commentée et tout devient 1: s dans gcc.false
mais si le modèle de fonction n'est pas commenté, il retourne soudainementtrue
: godbolt.org/z/zqxdk2Réponses:
std::is_constructible
doit retournerfalse
dans ce scénario car le constructeur n'est pas accessible.Comme indiqué sous la question, le comportement décrit dans la question est provoqué par un bogue dans GCC / libstdc ++. Le bogue est signalé ici et, selon Bugzilla, lié à s'il n'est pas provoqué par un bogue de contrôle d'accès pour les classes dans les fonctions de modèle qui n'a pas été résolu depuis un certain temps. La relation entre les deux bogues est tirée du commentaire Bugzilla de Jonathan Wakely qui semble avoir détecté la connexion entre les deux bogues en premier.
Cela est également impliqué par le fait que le comportement de ce scénario dans GCC devient correct lors de la suppression du constructeur au lieu de le rendre privé:
qui imprime
0
et00
respectivement. Il s'agit de la sortie correcte (quiclang
signale correctement dans le scénario avec un constructeur privé également).Cela pourrait expliquer le changement de comportement observé lors des commentaires dans la ligne, car à l'intérieur de la fonction dans la structure du modèle , la vérification d'accès ne fonctionne pas et signale que le constructeur est accessible lorsqu'il ne l'est pas. Lorsque le trait est vérifié à nouveau dans la ligne suivante ou éventuellement à un emplacement complètement différent (comme c'est le cas ici ), il a déjà été instancié et donne donc la mauvaise réponse.
la source