Klasa nie może uzyskać dostępu do własnej metody static constexpr - błąd Clanga?

28

Ten kod nie kompiluje się w Clang (6,7,8,9, trunk), ale dobrze się kompiluje w GCC (7.1, 8.1, 9.1):

template<class T> struct TypeHolder { using type = T; };

template<int i>
class Outer {
private:
    template<class T> 
    static constexpr auto compute_type() {
        if constexpr (i == 42) {
            return TypeHolder<bool>{};
        } else {
            return TypeHolder<T>{};
        }
    }

public:
    template<class T>
    using TheType = typename decltype(Outer<i>::compute_type<T>())::type;
};

int main() {
    Outer<42>::TheType<int> i;
}

Clang mówi mi:

<source>:17:49: error: 'compute_type' is a private member of 'Outer<42>'

... co oczywiście jest, ale staram się tego członka dostępem od wewnątrz tej samej klasy. Nie rozumiem, dlaczego nie powinno być tam dostępne. Czy trafiłem (i powinienem zgłosić) błąd Clanga?

Możesz bawić się kodem w eksploratorze kompilatorów Godbolt .

Lukas Barth
źródło
3
Najwyraźniej dodanie friend int main();powstrzymuje Clanga od narzekań.
HolyBlackCat
2
Zabawny! Jednak kontrola dostępu powinna być zdecydowanie przeprowadzona z „uprawnieniami” Outer<42>, a nie main- prawda? Wygląda mi jeszcze bardziej jak błąd.
Lukas Barth
Czy std::result_ofzamiast tego działa praca?
Brandon
FWIW, Działa również w ICC i MSVC.
ChrisMM

Odpowiedzi:

23

To podstawowy problem 1554 . Standard nie jest jasne, w jaki sposób przeprowadzane jest sprawdzanie dostępu dla szablonów aliasów (w kontekście definicji lub w kontekście użytkowania).

Bieżącym kierunkiem jest sprawdzenie w kontekście definicji, która poprawiłaby kod.

TC
źródło