To, co powiem poniżej (w ramach OLD POST ), powinno być do pewnego stopnia prawdziwe, ale faktyczny problem polega na tym, że SFINAE jest niewłaściwie używana, dlatego nie jestem już pewien, czy to błąd w gcc.
Deklaracja aliasu musi zawsze kończyć się powodzeniem, nie można tam SFINAE, ponieważ nie jest to deklaracja klasy ani funkcji ani specjalizacja (to ma sens, ponieważ nie można specjalizować aliasów). Jeśli deklaracja aliasu nie powiedzie się, program jest źle sformułowany. Dlatego kompilator może założyć, że nigdy nie dojdzie do przypadku, że deklaracja aliasu nie powiedzie się, dopóki nie zmusisz go do utworzenia takiego szablonu.
Dlatego jest całkowicie dopuszczalne, aby kompilator myślał, że tak sfinae_v_t<T,...>
jest zawsze T
, ponieważ tak się stanie, gdy program nie będzie źle sformułowany. Dlatego zobaczy, że we wszystkich przypadkach, w których program nie jest źle sformułowany, częściowa specjalizacja nie specjalizuje się i jako taka powie ci, że jest źle sformułowana. (Tak właśnie działa klang).
Nie sądzę, że kompilator jest do tego zmuszony. A jeśli tak nie jest i po prostu myśli „Ok, sfinae_v_t
to jakiś typ, cokolwiek.”, To nie jest oczywiste, że jest to powtórna deklaracja. Myślę więc, że dopóki nie stworzymy jednej z nich, nie ma nic złego w tym, że nie wyrzucimy błędu.
Ale kiedy go tworzymy, powinien występować problem polegający na tym, że mamy redeklarację lub że program jest źle sformułowany std::enable_if
, w zależności od argumentu szablonu. GCC powinno wybrać przynajmniej jedną z nich, ale nie ma żadnej.
Nie dotyczy to również absolutnie łatwiejszego przykładu bez std::enable_if
. Nadal uważam, że jest to błąd w GCC, ale jestem wystarczająco oszołomiony, że nie mogę już tego powiedzieć z całą pewnością. Powiedziałbym tylko, że ktoś powinien zgłosić to jako błąd i pozwolić ludziom z gcc myśleć o tym.
STARY POST
To jest błąd w gcc. Standard podaje nam zasady przekształcania szablonu klasy w szablony funkcji. Jeden szablon klasy jest bardziej wyspecjalizowany niż inny, jeśli jego funkcja jest ważniejsza niż druga w częściowym uporządkowaniu szablonu funkcji.
Utworzyłem tutaj funkcje , a teraz gcc twierdzi, że wywoływanie ich jest niejednoznaczne, dlatego musiałbym również powiedzieć, że szablony klas są jednakowo określone.
Uwaga: po dokładnym przeczytaniu standardu kompilator w mojej głowie zgadza się z clang.