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 .


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é.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.