Jakie są reguły, według których std::is_constructible
obsługuje się konstruktorów prywatnych? Biorąc pod uwagę następujący kod:
#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();
}
To drukuje 0
( ideone ), tzn. T
Nie jest domyślnie możliwe do zbudowania.
Komentując komentarz, drukuje 11
( ideone ), dzięki czemu T
nagle stała się domyślną konstrukcją.
Mogłem znaleźć uzasadnienie na poparcie obu wyników, ale nie rozumiem, w jaki sposób włączenie komentowanego wiersza zmienia wynik drugiego. Czy to w jakiś sposób wywołuje UB? Czy to błąd kompilatora? A może std::is_constructible
naprawdę jest to niespójne?
c++
typetraits
zennehoy
źródło
źródło
00
::value
wersja jest w stanie zmienić wyjście także tych, którzy się przed nim pojawili : godbolt.org/z/zCy5xU Odkomentuj komentarz i wszystko staje się 1: s w gcc.false
ale jeśli szablon funkcji nie jest komentowany, nagle zwracatrue
: godbolt.org/z/zqxdk2Odpowiedzi:
std::is_constructible
powinien powrócićfalse
w tym scenariuszu, ponieważ konstruktor jest niedostępny.Jak wskazano poniżej, zachowanie opisane w pytaniu jest spowodowane błędem w GCC / libstdc ++. Błąd jest tutaj zgłaszany i, zgodnie z Bugzillą, związany z, jeśli nie spowodowany, błędem kontroli dostępu dla klas w funkcjach szablonów , który był nierozwiązany od dłuższego czasu. Związek między dwoma błędami pochodzi z komentarza Bugzilli Jonathana Wakely'ego, który wydaje się, że najpierw wykrył połączenie między tymi dwoma błędami.
Jest to również sugerowane przez fakt, że zachowanie tego scenariusza w GCC staje się poprawne po usunięciu konstruktora zamiast uczynienia go prywatnym:
który drukuje
0
i00
odpowiednio. To jest poprawny wynik (któryclang
poprawnie raportuje w scenariuszu z prywatnym konstruktorem).To może tłumaczyć zaobserwowaną zmianę zachowania podczas komentowania w wierszu, ponieważ wewnątrz funkcji w strukturze szablonowej sprawdzanie dostępu nie działa i informuje, że konstruktor jest dostępny, gdy nie jest. Gdy cecha jest ponownie sprawdzana w następnym wierszu lub ewentualnie w zupełnie innym miejscu (tak jak ma to miejsce tutaj ), to już instancja, a tym samym daje złą odpowiedź.
źródło