La classe ne peut pas accéder à sa propre méthode constexpr statique privée - Bug Clang?

28

Ce code ne compile pas dans Clang (6,7,8,9, trunk), mais se compile très bien dans 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 me dit:

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

… Ce qui est bien sûr le cas, mais j'essaie d'accéder à ce membre depuis l' intérieur de la même classe. Je ne vois pas pourquoi il ne devrait pas y être accessible. Ai-je touché (et dois-je déposer) un bogue Clang?

Vous pouvez jouer avec le code dans l'explorateur de compilateur de Godbolt .

Lukas Barth
la source
3
Apparemment, l'ajout friend int main();empêche Clang de se plaindre.
HolyBlackCat
2
Drôle! Cependant, le contrôle d'accès doit certainement être effectué avec les "autorisations" de Outer<42>, non main- pas vrai? Me ressemblant encore plus à un bug maintenant.
Lukas Barth
Est-ce que l'utilisation std::result_offonctionne à la place?
Brandon
FWIW, fonctionne également en ICC et MSVC.
ChrisMM

Réponses:

23

Il s'agit du problème principal 1554 . La norme ne précise pas comment la vérification d'accès est effectuée pour les modèles d'alias (dans le contexte de la définition ou dans le contexte de l'utilisation).

La direction actuelle consiste à vérifier dans le contexte de la définition, ce qui rendrait votre code bien formé.

TC
la source