Информация об изменениях

Сообщение Re: Вопрос знатокам от 03.04.2023 17:28

Изменено 03.04.2023 17:43 rg45

Re: Вопрос знатокам
Здравствуйте, kov_serg, Вы писали:

_>
_>// header.h
_>template<class T> void f(T);

_>//template<> void f(int);

_>inline void fi(int x) { f(x); }
_>

_>
_>#include "header.h"

_>template<> void f(int x) {}
_>


_>Почему без явного объявления f(int) имеем грабли?


Таковы требования стандарта, явная специализация должна быть видна в точке использования:

https://timsong-cpp.github.io/cppwp/temp.expl.spec#7

If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.


_>Зачем так сделали?


Ну, наверное для того, чтоб компилятор не пытался выполнить инстанцирование праймари шаблона.

В документации по msvc есть вот такое описание ошибки: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c2908?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(C2908)%3Bk(vs.output)%26rd%3Dtrue&amp;view=msvc-170
Re: Вопрос знатокам
Здравствуйте, kov_serg, Вы писали:

_>
_>// header.h
_>template<class T> void f(T);

_>//template<> void f(int);

_>inline void fi(int x) { f(x); }
_>

_>
_>#include "header.h"

_>template<> void f(int x) {}
_>


_>Почему без явного объявления f(int) имеем грабли?


Таковы требования стандарта, явная специализация должна быть видна в точке использования:

https://timsong-cpp.github.io/cppwp/temp.expl.spec#7

If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.


_>Зачем так сделали?


Ну, наверное для того, чтоб компилятор не пытался выполнить инстанцирование праймари шаблона.

В документации по msvc есть вот такое описание ошибки: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c2908?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(C2908)%3Bk(vs.output)%26rd%3Dtrue&amp;view=msvc-170

P.S. То, что в этом примере используется шаблон класса, а не шаблон функции, ничего по сути не меняет — требование общее.