Создает ли указатель на шаблон экземпляр этого шаблона? - PullRequest
29 голосов
/ 05 декабря 2011

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

Причиной запроса является следующий код, который выдает ошибку при связывании времени с неопределенной ссылкой на 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 будет давать ошибку на обоих вызовах. Обычно я верю 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);
}

Ответы [ 2 ]

17 голосов
/ 05 декабря 2011

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

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

8 голосов
/ 05 декабря 2011

n3242 §14.7.1 / 1

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

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

n3242 §14.6.5 / 1

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...