Вопрос

Вот класс foo:

общий

Вот панель класса:

общий

Правильный ли синтаксис для наследования конструкторов?Если я использую "using foo :: foo;"тогда компилятор Visual C ++ 2010 умирает. Итак, как наследовать конструкторы из классов шаблонов в VC ++ 2010?

Это было полезно?

Решение

общий

Чтобы этот синтаксический анализ был правильным, вам нужно вставить template перед foo<T>;, чтобы сообщить компилятору, что foo следует рассматривать как имя шаблона (он не может заглядывать в foo<T>, чтобы сказать себя, поскольку код T неизвестен). Но использование кода ::template в объявлении using запрещено. Имя также не относится ко всем конструкторам bar: вместо этого оно будет относиться к определенной специализации шаблона функции конструктора (T является аргументом шаблона) такого конструктора следующим образом

общий

Кроме того, для объявления using недопустимо использовать код template-id (например, foo<T>) в качестве своего имени (что, по сути, запрещает ему ссылаться на специализацию шаблона функции, с добавлением запрета на указание специализаций шаблона функции преобразования имен) ), поэтому даже если вы исправите проблему синтаксического анализа с помощью ::template (если это будет возможно), вы все равно получите ошибку на этом этапе.

Когда были введены унаследованные конструкторы, были добавлены специальные правила, которые позволяют ссылаться на конструктор с помощью синтаксического правила: если у вас есть квалифицированный идентификатор (который в основном является квалифицированным именем с использованием кода ...::...), и последнее уточненное имя перед окончательными именами частей конкретный класс, то вы можете обозначить конструктор (ы) этого класса двумя дополнительными способами:

  • Если класс был назван с использованием идентификатора шаблона (имя формы foo<T>), а последняя часть соответствует имени шаблона (то есть, foo<T>::foo или TTP<T>::TTP с TTP является параметром шаблона шаблона).
  • Если последняя часть соответствует имени класса (например, foo::foo или T::T, при этом T является параметром шаблона).

Эти два дополнительных правила активны только в объявлении using. И их, естественно, не было в C ++ 03. Другое правило, которое также присутствовало в C ++ 03: если последняя часть называет имя внедренного класса, то это полное имя также относится к конструктору:

  • Сгенерировать кодовый код будет работать. Но только с этим правилом foo::foo (где T::T обозначает класс T) не будет работать, потому что foo не имеет члена с именем foo.

Поэтому, имея особые правила, вы можете писать

общий

Второе тоже верно: T - это имя внедренного класса, которое было внедрено в foo базового класса и унаследовано от foo<T>. Мы ссылаемся на это имя с помощью bar, а затем добавляем последнюю часть bar::foo, которая снова ссылается на имя внедренного класса, чтобы обозначить конструктор (ы) `foo.

Теперь вы понимаете, почему начальное имя, которое вы пробовали, могло бы относиться к специализации шаблона функции конструктора (если бы это было разрешено): потому что часть foo будет называть все конструкторы, а foo<T>::foo, который последует за этим, затем отфильтрует шаблон и передать аргумент типа.

Другие советы

Если ваш компилятор еще не поддерживает наследование конструкторов, но поддерживает макросы с переменным числом аргументов, шаблоны с переменным числом значений и ссылки на rvalue, а также действительно удобную функцию type_trait, вот действительно достойный обходной путь:

родовое слово

Если у вас еще нет is_constructible, основная идея работает и без него, но «унаследованный конструктор» будет слишком жадным.

вам не нужен второй параметр шаблона;

родовое слово

следует делать

edit Я утверждаю, что это работает на g ++ - 4.4.1, однако это должен быть правильный синтаксис, когда функция станет доступной

В других ответах уже хорошо объясняется, как работают наследование конструкторов в C ++ 0x.Однако на момент написания этой статьи ни один компилятор не реализовал полностью весь набор функций C ++ 0x.К сожалению, это означает, что VC ++ 2010 еще не поддерживает наследующие конструкторы.

Стандарт C ++ 0x еще не опубликован.Окончательный вариант стандарта будет завершен где-то вМарт , но у ISO потребуется еще несколько месяцев, чтобы опубликовать его.В течение этого времени разработчики компилятора внедряют функции, поэтому они будут максимально совместимы с C ++ 0x, когда стандарт будет завершен.

Я считаю, что последняя версия GCC поддерживает наследование конструкторов, поэтому, если вам нужно попробовать его сейчас, вы можете использовать это.Конечно, поддержка C ++ 0x является экспериментальной и может изменяться по мере обнаружения ошибок и т. Д.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top