Создает ли приведение к указателю на шаблон экземпляр этого шаблона?

StackOverflow https://stackoverflow.com/questions/8379002

Вопрос

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

Причиной запроса является следующий код, который выдает ошибку во время связывания с неопределенной ссылкой на check_error<char>(void*, long) с Clang и GCC 4.4.5, указывающий на то, что это не делает создайте экземпляр шаблона.MSVC и ССАГПЗ 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);
}
Это было полезно?

Решение

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

То, что Clang не следит за спецификацией здесь известно, и мне послал PR. Видеть http://llvm.org/bugs/show_bug.cgi?id=9440

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

n3242 §14.7.1/1

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

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

n3242 §14.6.5/1

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

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

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