Стандартные заголовки библиотеки для gcc 4.6 кажутся неправильными в этом случае, поскольку стандарт требует следующий конструктор (§20.7.2.2.1 / 16):
shared_ptr(const shared_ptr& r) noexcept;
, который является конструктором копированиякажется, что отсутствует в реализации gcc.Реализация, которую я имею под рукой (g ++ - 4.6.0), предлагает (в bits/shared_ptr.h
):
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r)
Но не имеет надлежащего конструктора копирования (шаблонный конструктор не может использоваться компилятором какконструктор копирования).Я нахожу странным, однако, что такая ошибка возникнет с производственным компилятором ...
EDIT Я пытался выяснить, почему именно g ++ 4.6 компилирует приведенный выше код сэто собственная стандартная библиотека.Кажется, что он воспринимает конструктор template
d как жизнеспособную перегрузку для создания копии, что заставило меня оглянуться назад к стандарту, чтобы убедиться, что это ошибка - у меня всегда было впечатление, что шаблон не можетиспользовался как конструктор копирования - или нет.
В стандарте C ++ 03 есть сноска 106)
Поскольку конструктор шаблона никогда не является конструктором копирования , наличие такого шаблона не подавляет неявное объявление конструктора копирования.Конструкторы шаблона участвуют в разрешении перегрузки с другими конструкторами, включая конструкторы копирования, и конструктор шаблона может использоваться для копирования объекта, если он обеспечивает лучшее соответствие, чем другие конструкторы.
Эта сноска не являетсяприсутствует в C ++ 11.Сноски не являются нормативными, поэтому должна быть другая цитата, поддерживающая эту заметку.Несколько параграфов ниже вы можете найти:
12.8 / 3 Объявление конструктора для класса X некорректно, если его первый параметр имеет тип (необязательно cv-квалифицированный) X илибо нет других параметров, либо все остальные параметры имеют аргументы по умолчанию. Шаблон функции-члена никогда не создается для выполнения копирования объекта класса в объект его типа.
Первая часть абзаца означает, что конструктор не может принятьтот же тип, что и аргумент (конструкторы копирования принимают ссылки, и разрешение такого конструктора вызовет неоднозначность), а также тот факт, что для него потребуется копирование в аргумент, для которого наилучшая перегрузка - при условии, что это запрещеноконструктор копирования-- будет той же функцией, которая, в свою очередь, потребует ... бесконечного цикла).
Во второй части предложения утверждается, что шаблонный конструктор не может использоваться для создания копий типа, что представляется нормативным разделом, поддерживающим сноску 106) .Теперь это было тщательно переписано в C ++ 11, чтобы заявить:
12.8 / 6 Объявление конструктора для класса X некорректно, если его первый параметр имеет тип (необязательно cv-qualified) X и либо нет других параметров, либо все остальные параметры имеют аргументы по умолчанию. Шаблон функции-члена никогда не создается для создания такой сигнатуры конструктора.
Теперь это означает, что ограничение шаблон нельзя использовать для копирования был удален и заменен менее строгим ограничением: шаблон не будет мгновенно создан для создания конструктора вида S( S )
, то есть такого, который может вызвать неоднозначность с конструктором копирования.
При этомс меньшим ограничением, кажется, что шаблонный конструктор выше может фактически использоваться как copy-конструктор , поскольку генерируемая им сигнатура совместима.Это поддерживает поведение компилятора g ++ 4.6 при обработке заголовка bits/shared_ptr.h
и подразумевает, что clang++
не может использовать шаблон в качестве допустимого конструктора.
Теперь следующий вопрос - соответствует ли стандартная реализация библиотеки, поставляемая с g ++ 4.6, или нет.Я не могу сказать от макушки головы.С одной стороны, отсутствует подпись конструктора, о которой я упоминал выше, поэтому вы можете утверждать, что она не соответствует требованиям.Но с другой стороны, совместимый компилятор должен подобрать шаблонный конструктор для достижения той же функциональности, и реализация будет вести себя , как если бы присутствовал этот конструктор.