Сделать параметр шаблона другом?

Пример:

template class Base { public: Base(); friend class T; }; 

Теперь это не работает … Есть ли способ сделать это?

Я на самом деле пытаюсь сделать общий герметик classа следующим образом:

 class ClassSealer { private: friend class Sealed; ClassSealer() {} }; class Sealed : private virtual ClassSealer { // ... }; class FailsToDerive : public Sealed { // Cannot be instantiated }; 

Я нашел этот пример на этом сайте, но я не могу его найти … ( здесь )

Я знаю, что есть другие способы сделать это, но сейчас мне интересно, действительно ли вы можете сделать что-то подобное.

Он явно запрещен в стандарте, даже если некоторые версии VisualStudio позволяют это делать.

Стандарт C ++ 7.1.5.3 Специфичные спецификаторы типов, параграф 2

В разделе 3.4.4 описано, как происходит поиск имени для идентификатора в специфицированном спецификаторе типа. Если идентификатор разрешает имя classа или имя-имя, специфицированный спецификатор типа вводит его в объявление так же, как спецификатор простого типа вводит его имя типа. Если идентификатор разрешен для параметра typedef-name или template-type, специфицированный тип-спецификатор плохо сформирован. [Примечание: это подразумевает, что внутри шаблона classа с типом-шаблоном T, class товарищей-друга T ; плохо сформирован. ]

Я признаю код выше как шаблон для печати (запретить расширение) classа. Существует еще одно решение, которое на самом деле не блокирует расширение, но оно будет равномерно отклоняться от classа. Как видно из исходной библиотеки ADOBE :

 namespace adobe { namespace implementation { template  class final { protected: final() {} }; }} #define ADOBE_FINAL( X ) private virtual adobe::implementation::final 

с использованием:

 class Sealed : ADOBE_FINAL( Sealed ) {//... }; 

Хотя он позволяет продлить, если вы действительно его заставляете:

 class SealBreaker : public Sealed, ADOBE_FINAL( Sealed ) { public: SealBreaker() : adobe::implementation::final(), Sealed() {} }; 

Это позволит пользователям ошибочно сделать это.

EDIT :

Предстоящий стандарт C ++ 11 позволяет вам подружиться с аргументом типа с немного другим синтаксисом:

 template  class A { // friend class T; // still incorrect: elaborate type specifier friend T; // correct: simple specifier, note lack of "class" }; 

Я нашел простой трюк, чтобы объявить параметры шаблона в качестве друзей:

 template < typename T> struct type_wrapper { typedef T type; }; template < typename T> class foo { friend class type_wrapper < T>::type }; // type_wrapper< T>::type == T 

Однако я не знаю, как это могло бы помочь определить альтернативную версию герметика classа.

Вам действительно нужно это делать? Если вы хотите, чтобы кто-то не получал ваш class, просто добавьте комментарий и сделайте деструктор не виртуальным.

  • Неопределенный символ в функции перегрузки оператора шаблона
  • Частичный порядок шаблонов - почему частичный вывод преуспевает здесь
  • Interesting Posts

    Коллекция Controls не может быть изменена, поскольку элемент управления содержит блоки кода (т.е. )

    Как закодировать счетчик для ожидающих процессов в пакетном файле?

    WPF, «Ссылка на объект не установлена ​​в экземпляр объекта» в Designer

    Заменить «Paint» в качестве программы по умолчанию для команды «Изменить» проводника

    Как работает Math.Pow (и так далее)

    Получение относительного виртуального пути с физического пути

    Обновить R с помощью RStudio

    Как использовать performSelector: withObject: afterDelay: с примитивными типами в cocoa?

    Mac Terminal – ошибка «указатель освобождается не была» при открытии терминала

    Заголовок C99 stdint.h и MS Visual Studio

    Как я могу проверить, какая версия EL используется сервером

    Нужен ли мне тип контента для HTTP-запросов?

    Закрытие в Java 7

    Лучший способ автоматической привязки данных между базой данных и пользовательским интерфейсом в приложении java swing?

    Извлечь имя файла и расширение в Bash

    Давайте будем гением компьютера.