Подтвердить что ты не робот

Создает ли кастинг указатель на шаблон для создания шаблона?

static_cast<the_template<int>*>(0) - создает ли этот экземпляр the_template с типом int?

Причиной для запроса является следующий код, который приведет к ошибке при связывании времени с ссылкой undefined на check_error<char>(void*, long) с помощью Clang и GCC 4.4.5, что указывает на то, что он не создает экземпляр шаблона. MSVC и GCC 4.5.1, однако компилировать и связывать просто отлично, что приводит к тому, что он создает экземпляр шаблона. Однако, если вы не учитываете листинг, MSVC и GCC (как 4.4.5, так и 4.5.1) будут ошибочными только в check_error<char> (желаемое поведение), в то время как Clang будет ошибкой при обоих вызовах. Обычно я верю Клану, когда дело доходит до подходящего материала, но мне интересно:

Какой компилятор прав и что говорит об этом стандарт?


#include <type_traits>

template<class T>
void check_error(void*, long);

template<class T>
struct foo{
  template<class U>
  friend typename std::enable_if<
    std::is_same<T,U>::value
  >::type check_error(foo<T>*, int){}
};

template struct foo<int>;

int main()
{
  check_error<int>(static_cast<foo<int>*>(0), 0);
  check_error<char>(static_cast<foo<char>*>(0), 0);
}
4b9b3361

Ответ 1

Это не приведение, которое создает экземпляр специализации шаблона класса, а вызов функции, потому что аргумент вызывает ADL. Создание экземпляра выполняется потому, что его полнота может повлиять на семантику программы.

Этот clang не следует спецификации здесь известно, и PR был отправлен мной некоторое время назад. См. http://llvm.org/bugs/show_bug.cgi?id=9440

Ответ 2

n3242 §14.7.1/1

Если спецификация шаблона класса явно не была создана (14.7.2) или явно специализирована (14.7.3), специализация шаблона класса неявно создается, когда специализация ссылается в контексте для которого требуется полностью определенный тип объекта или когда полнота типа класса влияет на семантику программы. Неявное создание экземпляра специализации шаблона шаблона вызывает неявное создание деклараций, но не определение или аргументы по умолчанию, функций-членов класса, классы-члены, статические элементы данных и шаблоны-члены; и это вызывает неявное создание определений членских анонимных союзов. Если член шаблона класса или шаблон участника был явно инстанцирован или явно специализирован, специализация члена неявно создается когда специализация ссылается в контексте, который требует определения члена; в в частности, инициализация (и любые связанные с ней побочные эффекты) статического члена данных не происходит, если элемент статических данных сам используется таким образом, который требует определения статического члена данных.

Мне кажется, что static_cast потребует создания объявлений, но не определений (поскольку вы просто имеете дело с указателями).

n3242 §14.6.5/1

Классы или функции друзей могут быть объявлены в шаблоне класса. Когда шаблон создается, имена его друзей рассматриваются так, как если бы специализация была явно объявлена ​​в момент ее создания.

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