Вопрос по private-members, c++, templates – Частные шаблоны классов / структуры видимости

3

Я не понимаю, почему в следующем коде мне разрешено создавать функцииprint_private_template пока компилятор жалуетсяprint_private_class:

#include <cstdio>

class A
{
    private:
        template <unsigned T>
        struct B
        {

        };

        struct C
        {

        };

    public:
        template <unsigned T>
        B<T> getAb()
        { 
            return B<T>();
        }

        C getAc()
        { 
            return C();
        }
};

template<unsigned T>
void print_private_template(const A::B<T> &ab)
{
    printf("%d\n", T);
}

void print_private_class(const A::C &ac)
{
    printf("something\n");
}

int main(int, char**)
{
    A a;

    print_private_template(a.getAb<42>());

    print_private_class(a.getAc());

    return 0;
}

Это ожидаемое поведение? ошибка / расширение компилятора?

Просто чтобы прояснить, моя цель - сделать ошибку компилятора наи то и другое использованиеprint_private_template а такжеprint_private_class.

они оба вызывают ошибку компилятора в MSVC2008 YeenFei

Ваш Ответ

2   ответа
0

GCC не выполняет управление доступом при создании экземпляров шаблонных структур / классов, вложенных в другие (шаблонные) структуры / классы.

Один из способов обойти это - заключить их в не шаблонную структуру:

template<int I> class MyTemplate
{
    struct PT
    {
        template<int, typename = void> struct InnerTemplate;
        // ... specialisations here ...
    };
public:
    typedef typename PT::template InnerTemplate<I>::SomeType SomeType;
};
typedef MyTemplate<1>::PT::InnerTemplate<1> ThisWontWork;

Последняя строка не скомпилируется с ошибкой:

error: 'struct MyTemplate<1>::PT' is private within this context

Я признаю, что это некрасиво, особенно при использованииPT::template но это, кажется, эффективно предотвращает создание клиентами шаблонов помощников, к которым они не предназначены, так что стоит попробовать.

2

Комео выдает ошибку (когда вы закомментируетеprint_private_class функция и ее вызов в строгом режиме C ++ 03.

ComeauTest.c (31): ошибка: шаблон класса "A :: B" (объявлен в строке 7) недоступен. Vid print_private_template (const A :: B & ab) ^ обнаружен во время создания экземпляра "print_private_template" на основе аргумента шаблона <42U> в строке 45

G ++ 4.5 в Windows не сообщает об ошибке с-std=c++ -Wall -pedantic хоть.

Твой классA::C и шаблон классаA::B<T> оба имеют ту же видимость, что и любые другие обычные члены. Следовательно, обаprint_private_class а такжеprint_private_template требует диагностики.

11.8. Вложенные классы [Class.access.nest]

1 Вложенный класс является членом, и поэтому имеет те же права доступа, что и любой другой член. Члены включающего класса не имеют специального доступа к членам вложенного класса; должны соблюдаться обычные правила доступа (пункт 11).

Я так понимаю, я нашел ошибку компилятора в GCC тогда? LiraNuna
Я использую GCC 4.4.3, поэтому сомневаюсь, что проблема связана с вашей нестабильной сборкой. LiraNuna
IIRC, GCC 4.5 (тот, который я использую) является экспериментальной сборкой. Там должны быть некоторые проблемы с качеством реализации. Но, да, конечно, вы можете пойти дальше и подать это. dirkgently
Гектометр Внутренние классы работали с большинством компиляторов до недавнего времени. Я вижу, вы уже подали ошибку (gcc.gnu.org/bugzilla/show_bug.cgi?id=45775 для других). Надеюсь, это скоро исправят! dirkgently
Вау, это похоже на ДЕЙСТВИТЕЛЬНО старую ошибку! Я могу воспроизвести это из GCC 3.4 и выше! GCC 3.3 ошибки, как и должно быть, хотя. LiraNuna

Похожие вопросы