Создает ли приведение к указателю на шаблон экземпляр этого шаблона?
-
28-10-2019 - |
Вопрос
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
Дружественные классы или функции могут быть объявлены в шаблоне класса.При создании экземпляра шаблона имена его друзей обрабатываются так, как если бы специализация была явно объявлена в момент создания экземпляра.
Я думаю, что это должно быть связано, но, возможно, кто-то другой сможет интерпретировать лучше, чем я.