Класс не может получить доступ к своему собственному статическому методу constexpr - ошибка Clang?


28

Этот код не компилируется в Clang (6,7,8,9, транк), но прекрасно компилируется в 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 говорит мне:

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

... что, конечно, есть, но я пытаюсь получить доступ , что элемент из внутри одного класса. Я не понимаю, почему это не должно быть доступно там. Я ударил (и я должен подать) ошибку Clang?

Вы можете поиграть с кодом в проводнике компилятора Годболта .


3
Очевидно добавление friend int main();останавливает Clang от жалоб.
HolyBlackCat

2
Веселая! Тем не менее, проверка доступа обязательно должна быть сделана с «разрешениями» Outer<42>, не так mainли? Выглядит даже больше как ошибка для меня сейчас.
Лукас Барт

Работает ли std::result_ofвместо этого?
Брэндон

FWIW, также работает в ICC и MSVC.
ChrisMM

Ответы:


23

Это основной вопрос 1554 . В стандарте неясно, как выполняется проверка доступа для шаблонов псевдонимов (в контексте определения или в контексте использования).

Текущее направление - это проверка в контексте определения, которое сделает ваш код правильно сформированным.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.