Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
 Аватар для SomniPhobia
602 / 439 / 137
Регистрация: 22.11.2017
Сообщений: 1,407

Инстанцирование и специализация шаблона

21.08.2023, 07:51. Показов 4718. Ответов 40
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
В чём различия инстанцирования от специализации при объявлении?

C++
1
2
3
4
5
6
template <typename T> void func(T param)
{}
//инстанцирование
template void func<int>(int param);
//специализация
template <> void func<int>(int param);
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.08.2023, 07:51
Ответы с готовыми решениями:

Инстанцирование шаблона
Есть шаблонная очередь с использованием vector Как инстанцировать для своего класса, представляющего строку, изготовленную из...

Инстанцирование шаблона
Существует шаблон следующего вида: template&lt;class T, int size&gt; void foo(T (&amp;array)) { cout &lt;&lt; size &lt;&lt; endl; } И следующий...

Инстанцирование шаблона во время выполнения
Добрый вечер! Компилятор требует константное выражение передаваемое в шаблон, как это можно обойти? мб с помощью каких то заклинаний над...

40
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
24.08.2023, 09:46
Студворк — интернет-сервис помощи студентам
IGPIGP, можно вот так взглянуть:

шаблон - это чертёж будущей сущности.
специализация - это тоже чертёж, только с исправлениями

(на данный момент в "физическом" коде ещё ничего не появилось, то есть шаблон никакого машинного кода не породит сам по себе)

инстанцирование (явное или неявное) - это применение компилятором чертежа и создание "физической" сущности в коде
2
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
24.08.2023, 11:14
Алексей1153, да - именно так я и думаю. У этих вещей (явное инстанцирование и явная специализация) разное назначение, но одна может использовать другую, а другая, - нет. То есть, в ваших терминах, инстанцирование использует наиболее актуальный чертёж, на момент своего осуществления)
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
24.08.2023, 16:57
Цитата Сообщение от IGPIGP Посмотреть сообщение
Если вас эта мантра удовлетворяет, то меня нет и я пытаюсь найти ответ почему.
Зачем его искать, если здесь все мгновенно очевидно?

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

По этой причине, если во время компиляции явное инстанцирование "знает" о существовании явной специализации (то есть явная специализация расположена выше в единице трансляции), то явное инстанцирование ничего не делает. Здесь все логично: считаем, что явное инстанцирование просто ссылается на явную специализацию. Если же явное инстанцирование "не знает" о существовании явной специализации, то мы имеем очевидную проблему. А сумеет ли реализация диагностировать эту проблему - зависит от качества реализации.

Я бы ожидал, что "обратное" расположение явного инстанцирования и явной специализации в одной единице трансляции (как в примере ТС) будет отлавливаться всеми уважающими себя реализациями. И это так. А явное инстанцирование и явная специализация, разбросанные по разным единицам трансляции, будут отлавливаться уже линкером - как множественные определения. И это так. Но по-видимому тут есть еще какие-то нюансы, вследствие которых стандарт говорит, что диагностика не требуется.

Все просто и понятно сразу. Ничего тут не надо искать.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
24.08.2023, 17:11
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Зачем его искать, если здесь все мгновенно очевидно?
Нет. Не очевидно. Если вы и правда этого не поняли, то я всё уже написал и другие участники смогли понять. Логика, действительно не сложна. Но не очевидна.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
24.08.2023, 17:56
Цитата Сообщение от Алексей1153 Посмотреть сообщение
специализация - это тоже чертёж, только с исправлениями
Нет, грубейше не верно. Ключевое (!) свойство явной специализации в рамках этой темы заключается именно в том, что явная специализация - это уже ни в коем случае не "чертеж", а готовый завершенный финальный результат, отлитый в граните.

Постарайтесь заучить простое правило, которое я здесь уже не раз приводил (но почему-то оно все никак не прививается): когда в шаблоне (функции, класса и т.п.) больше не осталось свободных шаблонных параметров, то шаблон перестает быть шаблоном и превращается в обычную классическую сущность (функцию, класс и т.п.). В частности, эта сущность перестает вести себя как шаблон и начинает вести себя как обычная сущность в отношении ODR.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
(на данный момент в "физическом" коде ещё ничего не появилось, то есть шаблон никакого машинного кода не породит сам по себе)
инстанцирование (явное или неявное) - это применение компилятором чертежа и создание "физической" сущности в коде
... и, как следствие, это тоже неверно. Согласно вышеприведенному мною правилу, явная специализация - это не "чертеж" функции, а обычная функция. Она сразу (!) порождает код, как и любая обычная функция, независимо от того, "инстанцирована" она или нет. Компилятор вынужден порождать код для явных специализаций функций сразу, потому что где-то в другой единице трансляции может присутствовать обращение к этому коду. Компилятор не знает и не может знать, есть ли где-то такие обращения. Поэтому у него нет выбора - он вынужден всегда сразу и безусловно генерировать код для явных специализаций (то есть все обстоит точно так же, как и с обычными функциями).

(Где, кто и когда "порождает код" - это, конечно, детали реализации, но традиционные реализации ведут себя именно так и стандарт языка написан в расчёте именно на такие реализации.)

---

Цитата Сообщение от IGPIGP Посмотреть сообщение
Нет. Не очевидно. Если вы и правда этого не поняли, то я всё уже написал и другие участники смогли понять.
Нет, нет... Вся путаница, которая тут существовала, связана лишь с бессмысленностью исходного вопроса о неких "различиях", когда речь идет о совершенно несравнимых сущностях. Я сразу закрыл эту тему уже в сообщении #2.

Что же касается остального, то это было: 1. разбор вашего вообще никак не относящегося к теме вброса про некое "разбухание" кода, 2. общее непонимание некоторыми участниками дискуссии того, что такое явная специализация и явное инстанцирование. Я думаю, что я все достаточно подробно все разобрал и объяснил в своих сообщениях выше.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
24.08.2023, 19:04
https://www.open-std.org/JTC1/... /n3797.pdf
4 An instantiated template specialization can be either implicitly instantiated (14.7.1) for a given argument
list or be explicitly instantiated (14.7.2). A specialization is a class, function, or class member that is either
instantiated or explicitly specialized (14.7.3).
5 For a given template and a given set of template-arguments,
— an explicit instantiation definition shall appear at most once in a program,
— an explicit specialization shall be defined at most once in a program (according to 3.2), and
— both an explicit instantiation and a declaration of an explicit specialization shall not appear in a
program unless the explicit instantiation follows a declaration of the explicit specialization.
An implementation is not required to diagnose a violation of this rule.
4. Экземпляр специализации шаблона может быть либо неявно создан (14.7.1) для заданного аргумента.
список или быть явно инстанцированным (14.7.2). Специализация — это класс, функция или член класса, который либо
экземпляры или явно специализированные (14.7.3).
5 Для данного шаблона и данного набора аргументов шаблона,
- явное определение экземпляра должно появляться в программе не более одного раза,
— явная специализация должна быть определена в программе не более одного раза (согласно 3.2), и
- как явное инстанцирование, так и объявление явной специализации не должны появляться в
программы, если только явное создание экземпляра не следует за объявлением явной специализации.
Реализация не требуется для диагностики нарушения этого правила.
выделю:
- как явное инстанцирование, так и объявление явной специализации не должны появляться в
программы, если только явное создание экземпляра не следует за объявлением явной специализации.
Реализация не требуется для диагностики нарушения этого правила.

То есть, стандарт выделяет случай когда
явное создание экземпляра следует за объявлением явной специализации
Кроме того. Стандарт трактует явную специализацию как объявление. Инстанцирование может произойти позже - при вызове в коде.
4. Экземпляр специализации шаблона может быть либо неявно создан (14.7.1) для заданного аргумента.
список или быть явно инстанцированным (14.7.2).
А вот явное инстанцирование (как и любое другое) он трактует как определение и создание экземпляра. Для функции это код в секции кода объектного файла.
Впрочем, об этом своими словами я уже писал. Это моя последняя попытка что-то объяснить.

Добавлено через 19 минут
в параграфе § 14.7.2 на который ссылается первая цитата
A definition of a class template, a member class of a class template, or a member class
template of a class or class template shall precede an explicit instantiation of that entity unless the explicit
instantiation is preceded by an explicit specialization of the entity with the same template arguments.
та же оговорка о том что явному инстанцированию может предшествовать явная специализация.
И кстати. Стандарт разделяет определение и декларацию явного инстанцирования. И декларацией считается выражение предваряемое ключевым словом extern. То есть, это вещи похожие и очень близки но разные. Разные.

Добавлено через 3 минуты
вот тут об этом (см. в самом низу цитаты:
14.7.2 Explicit instantiation [temp.explicit]
1 A class, function, variable, or member template specialization can be explicitly instantiated from its template.
A member function, member class or static data member of a class template can be explicitly instantiated
from the member definition associated with its class template. An explicit instantiation of a function template
or member function of a class template shall not use the inline or constexpr specifiers.
2 The syntax for explicit instantiation is:
explicit-instantiation:
externopt template declaration
There are two forms of explicit instantiation: an explicit instantiation definition and an explicit instantiation declaration. An explicit instantiation declaration begins with the extern keyword.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
24.08.2023, 20:33
Цитата Сообщение от IGPIGP Посмотреть сообщение
Совершенно верно. То есть слово в слово то, что я сказал выше. Оттуда и взято.

Цитата Сообщение от IGPIGP Посмотреть сообщение
выделю:
- как явное инстанцирование, так и объявление явной специализации не должны появляться в
программы, если только явное создание экземпляра не следует за объявлением явной специализации. Реализация не требуется для диагностики нарушения этого правила.
Совершенно верно. То есть слово в слово то, что я сказал выше.

Цитата Сообщение от IGPIGP Посмотреть сообщение

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

Цитата Сообщение от IGPIGP Посмотреть сообщение
Кроме того. Стандарт трактует явную специализацию как объявление. Инстанцирование может произойти позже - при вызове в коде.
Нет, тут вы запутались. В языке С++ определение функции одновременно является ее объявлением. Постарайтесь запомнить базовое правило: когда стандарт говорит об объявлениях, это значит, что речь идеи о всех формах объявлений, включая определения. В данном случае различие просто не имеет никакого значения.

Что же касается "инстанцирования": нет, никакого "инстанцирования явной специализации" произойти не может. Понятие "инстанцирования" к явной специализации неприменимо.

Цитата Сообщение от IGPIGP Посмотреть сообщение
А вот явное инстанцирование (как и любое другое) он трактует как определение и создание экземпляра.
Для функции это код в секции кода объектного файла.
... Кроме случаев, когда явное инстанцирование ссылается на соответствующую явную специализацию, в каковом случае явное инстанцирование не делает вообще ничего, т.е. просто игнорируется, как ясно написано открытым текстом в стандарте языка.

Почему это происходит я уже подробно объяснил в предыдущих сообщениях, и для закрепления повторил здесь: понятие "инстанцирования" к явной специализации неприменимо.

Цитата Сообщение от IGPIGP Посмотреть сообщение
И кстати. Стандарт разделяет определение и декларацию явного инстанцирования. И декларацией считается выражение предваряемое ключевым словом extern. То есть, это вещи похожие и очень близки но разные. Разные.
Совершенно верно. То есть слово в слово то, что я сказал выше. Вы узнали об этом из моего сообщения №8 в этой теме. То есть материал все таки усваивается, но вижу, что и отсебятину еще вычищать и вычищать..
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
24.08.2023, 21:10
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Кроме случаев, когда явное инстанцирование ссылается на соответствующую явную специализацию, в каковом случае явное инстанцирование не делает вообще ничего, т.е. просто игнорируется, как ясно написано открытым текстом в стандарте языка.
Покажите где. Я вам показал, что явная специализацмя инстанцируется после её объявления. Явное инстанцирование - возможный вариант. То есть оно таки не ничего не делает, а делает то что обычно.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
овершенно верно. То есть слово в слово то, что я сказал выше. Вы узнали об этом из моего сообщения №8 в этой теме. То есть материал все таки усваивается, но вижу, что и отсебятину еще вычищать и вычищать..
Я просто хотел ещё раз повторить то, что явное инстанцирование - определение, может не зависеть от того есть ли хоть один вызов в его единице трансляции. Достаточно того, что в других единицах есть extern ссылки на данное определение в файле, где оно даже не вызывается ни разу. И это определение нужно. И оно свободно может и должно следовать за явной специализацией, если таковая нужна для определения какой-то логики. Основной шаблон может быть неполным типом (объявлен только), в конце концов.
TheCalligrapher, не нужно меня поучать запомнить, что-то. Это не подействует.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
24.08.2023, 21:14
Цитата Сообщение от IGPIGP Посмотреть сообщение
TheCalligrapher, не нужно меня поучать запомнить, что-то. Это не подействует.
¯\_(ツ)_/¯

---

Желающим разбираться в таких вопросах сразу скажу: все это вытекает из и опирается на классический принцип раздельной компиляции, на котором исторически базируются все реализации С и С++. Все, что вы читаете в стандарте на тему ODR, на тему явного и неявного инстанцирования шаблонов, на тему явной специализации и т.д. и т.п. будет всегда опираться на соображения, ориентированные на поддержку классического принципа раздельной компиляции.

Если вы разберетесь, как на практике работает раздельная компиляция в С++ (особенно с шаблонами), вам в большинстве не нужно будет заглядывать в стандарт языка для того, чтобы найти описания интересующего вас поведения. То, что я объяснял выше, вам будет сразу интуитивно понятно само собой, самоочевидно. Ничего сложного в том, как организована раздельная компиляция в С++ нет, но ее понимание сразу позволит вам самостоятельно "дедуцировать" и/или понять огромные куски спецификации языка.

Если же вы не понимаете и не хотите понимать, как работает раздельная компиляция в С++, то попытки читать стандарт на рассматриваемую тему лишь завалят вас нагромождениями абстрактной информации, которая при этом перемешается с вашей и чужой отсебятиной. Что мы, в частности, и наблюдаем в данном случае.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.08.2023, 00:19
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Желающим разбираться в таких вопросах сразу скажу: все это вытекает из и опирается на классический принцип раздельной компиляции, на котором исторически базируются все реализации С и С++. Все, что вы читаете в стандарте на тему ODR, на тему явного и неявного инстанцирования шаблонов, на тему явной специализации и т.д. и т.п. будет всегда опираться на соображения, ориентированные на поддержку классического принципа раздельной компиляции.
Если вы разберетесь, как на практике работает раздельная компиляция в С++ (особенно с шаблонами), вам в большинстве не нужно будет заглядывать в стандарт языка для того, чтобы найти описания интересующего вас поведения. То, что я объяснял выше, вам будет сразу интуитивно понятно само собой, самоочевидно. Ничего сложного в том, как организована раздельная компиляция в С++ нет, но ее понимание сразу позволит вам самостоятельно "дедуцировать" и/или понять огромные куски спецификации языка.
Если же вы не понимаете и не хотите понимать, как работает раздельная компиляция в С++, то попытки читать стандарт на рассматриваемую тему лишь завалят вас нагромождениями абстрактной информации, которая при этом перемешается с вашей и чужой отсебятиной. Что мы, в частности, и наблюдаем в данном случае.
Демагогия опирающаяся на то, что кроме вас никто ничего не понимает. А аргументы? Я задал вам вопрос по вашему же тексту. Вы показываете мантры и заклинания, вместо того, что должны бы показать.
Вы писали:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Что же касается "инстанцирования": нет, никакого "инстанцирования явной специализации" произойти не может. Понятие "инстанцирования" к явной специализации неприменимо.
Цитата Сообщение от Сообщение от IGPIGP
А вот явное инстанцирование (как и любое другое) он трактует как определение и создание экземпляра.
Для функции это код в секции кода объектного файла.
... Кроме случаев, когда явное инстанцирование ссылается на соответствующую явную специализацию, в каковом случае явное инстанцирование не делает вообще ничего, т.е. просто игнорируется, как ясно написано открытым текстом в стандарте языка.
я выделю:
когда явное инстанцирование ссылается на соответствующую явную специализацию, в каковом случае явное инстанцирование не делает вообще ничего, т.е. просто игнорируется, как ясно написано открытым текстом в стандарте языка.
как ясно написано открытым текстом в стандарте языка.
я спросил по русски:
Цитата Сообщение от IGPIGP Посмотреть сообщение
Покажите где.
Будете показывать или продолжите говорить о важности понимания и без стандарта?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
25.08.2023, 00:42
Цитата Сообщение от IGPIGP Посмотреть сообщение
я выделю:
как ясно написано открытым текстом в стандарте языка.
я спросил по русски:
Когда я что-то говорю о языке С++, поиск соответствующих мест в стандарте - ваша задача. Я оставляю это вам в качестве домашнего задания. Которое вы успешно выполнили выше, судя по всему для того, чтобы заработать какие-то баллы в моих глазах. Но как так получилось, что старательно найдя в стандарте подтверждения всему, что я говорил выше, вы не смогли самостоятельно найти этот маленький кусочек

http://eel.is/c++draft/temp.explicit#7
7 For a given set of template arguments, if an explicit instantiation of a template appears after a declaration of an explicit specialization for that template, the explicit instantiation has no effect.
- ума не приложу.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.08.2023, 02:38
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Когда я что-то говорю о языке С++, поиск соответствующих мест в стандарте - ваша задача.
Искать аргументы за Вас? Увольте. Вы говорите - извольте аргументировать или оставайтесь черной кошкой в тёмной комнате.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Я оставляю это вам в качестве домашнего задания.
Ростом не вышли так фантазировать. Учите кого-то кто согласен и даст вам такое право. Мне таких даже и не жалко.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Которое вы успешно выполнили выше, судя по всему для того, чтобы заработать какие-то баллы в моих глазах.
Тщеславие всегда проявляет слабость. Интеллектуальную в том числе. Пусть мои мотивы вас не возбуждают. Они вас не касаются.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Но как так получилось, что старательно найдя в стандарте подтверждения всему, что я говорил выше, вы не смогли самостоятельно найти этот маленький кусочек
Опять высокомерие и недосказанность. Это всё не случайно, я уверен. Но тут я не помог бы даже если бы хотел. Не специалист, потому что. Но и если бы смог не стал бы. Не мазохист, потому что.
Я подозреваю, что нет в стандарте утверждения о том, что явное инстанцирование после явной специализации "ничего не делает", хотя допустимо синтаксически (или как-то так). И вам показать нечего. Нет ссылки и вы ведёте себя... Ну неожиданно, скажем. Я видел вас в разных ситуациях, но не в такой.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
25.08.2023, 02:47
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я подозреваю, что нет в стандарте утверждения о том, что явное инстанцирование после явной специализации "ничего не делает", хотя допустимо синтаксически (или как-то так). И вам показать нечего.
¯\_(ツ)_/¯ Остаётся лишь, в который уж раз, заметить - тут все понятно...

—-

Я достаточно подробно раскрыл тему и, надеюсь, посторонний шум не помешал остальным участникам обсуждения подчеркнуть для себя что-то новое в ее понимании. Я думаю, все здесь уже научились этот шум игнорировать. Если дальнейших вопросов нет, будем считать обсуждение закрытым.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.08.2023, 15:52
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Остаётся лишь, в который уж раз, заметить - тут все понятно...
Абсолютно. Смотрите, я задавал вопрос:
Цитата Сообщение от IGPIGP Посмотреть сообщение
Покажите где.
То есть, - где конкретно сказано, что
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
когда явное инстанцирование ссылается на соответствующую явную специализацию, в каковом случае явное инстанцирование не делает вообще ничего, т.е. просто игнорируется
Вопрос был тут:
https://www.cyberforum.ru/post17014687.html
потом был
https://www.cyberforum.ru/post17014693.html
без ответа на вопрос
А пост
https://www.cyberforum.ru/post17014811.html
был размещён в два приёма. Причём первая часть противоречит второй. Она провоцирующая и спровоцировала мой ответ.
Вот так это выглядело вначале:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Когда я что-то говорю о языке С++, поиск соответствующих мест в стандарте - ваша задача. Я оставляю это вам в качестве домашнего задания. Которое вы успешно выполнили выше, судя по всему для того, чтобы заработать какие-то баллы в моих глазах. Но как так получилось, что старательно найдя в стандарте подтверждения всему, что я говорил выше, вы не смогли самостоятельно найти этот маленький кусочек
а когда появилось таки объяснение:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
http://eel.is/c++draft/temp.explicit#7
7 For a given set of template arguments, if an explicit instantiation of a template appears after a declaration of an explicit specialization for that template, the explicit instantiation has no effect.
- ума не приложу.
Я уже писал свой свой ответ. Дело было поздней ночью и возможно, прочитав первую часть я уже не стал читать вторую? Вряд ли, но может быть и такое.
Сегодня прочитав тот пост полностью в том виде как он есть сейчас я уже увидел ответ и ссылку и цитату.
Бог с ним.
Могу лишь отметить., что в стандарте написано если не противоречиво, то двусмысленно.
Мой небольшой эксперимент показал, что объявление явного инстанцирования (extern), может ссылаться как на определение явного инстанцирования, так и на объявление явной специализации. Получается, что объявление явной специализации включает определение явного инстанцирования и при последовательном размещении поглощает его. Поэтому, явное инстанцирование после явной специализации остаётся не у дел.
Это можно было бы изложить по-человечески придерживаясь иерархии понятий. Однако в стандарте это сделано в виде декларативной юридической нормы. Хороший кусок хлеба для зубрил на память.
Вот файлики которые могут продемонстрировать сказанное:
один заголовочник
C++
1
2
3
4
5
6
//some_template_fn.h
#ifndef SOME_TEMPLATE_FN_H_INCLUDED
#define SOME_TEMPLATE_FN_H_INCLUDED
template<typename T>
void some_template_fn(T t);
#endif // SOME_TEMPLATE_FN_H_INCLUDED
и два исходника:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
////some_template_fn.cpp
#include"some_template_fn.h"
#include <iostream>
 
//это определение вообще можно убрать
//если нет других явных инстанцирований:
template<typename T>
void some_template_fn(T t)
{
    std::cout<<t<<'\n';
}
 
//получается, что явная специализация включает инстанцирование
template<>
void some_template_fn<int>(int t)
{
    std::cout<<"t is int "<<t<<'\n';
}
 
//это уже не требуется так как extern объявлению
//достаточно явной специализации
//то есть выходит что явная специализация это явное инстанцироване+
//конкретизирующее определение для конкретного набора типов
//template void some_template_fn<int>(int);
и точка входа:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "some_template_fn.h"
 
extern  template void some_template_fn<int>(int);
 
int main()
{
   some_template_fn(123);
    return 0;
}
Что касается раскрытия темы... оно случилось.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
25.08.2023, 16:30
Цитата Сообщение от IGPIGP Посмотреть сообщение
А пост
https://www.cyberforum.ru/post17014811.html
был размещён в два приёма. Причём первая часть противоречит второй. Она провоцирующая и спровоцировала мой ответ.
Нет. Цитата из стандарта была включена мною в пост сразу.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Могу лишь отметить., что в стандарте написано если не противоречиво, то двусмысленно.
Нет, в стандарте никакой двусмысленности нет. Кроме, разумеется, той "двусмысленности", которая всегда присутствует в неопределенном поведении, например.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Мой небольшой эксперимент показал, что объявление явного инстанцирования (extern), может ссылаться как на определение явного инстанцирования, так и на объявление явной специализации.
Нет, не может. Ваш эксперимент "показал", что в ситуации, когда реализация не выдала диагностического сообщения в ответ на ошибочную программу (пользуясь тем, что диагностика таких ошибок не требуется), программа имеет неопределенное поведение. Ваш "эксперимент" - не более чем очередное глубокомысленное разглядывание неопределенного поведения с далеко идущими выводами - "мой небольшой эксперимент показал". Ага, "показал"... Эксперименты с неопределенным поведением ничего никогда не показывают, кроме неопределенного поведения.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Получается, что объявление явной специализации включает определение явного инстанцирования и при последовательном размещении поглощает его.
Нет.

Либо явное инстанцирование строго следует за явной специализацией в каждой единице трансляции, в которых они присутствуют (к каковом случае явное инстанцирование "ничего не делает"), либо программа ошибочна (диагностика не требуется). Если реализация не выдала диагностики в последнем случае, то поведение программы не определено.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Вот файлики которые могут продемонстрировать сказанное:
Программа ошибочна, диагностика не требуется. Если компилятор не выдал диагностики в ответ на эту программу, то ее поведение не определено. Это все, что она "может продемонстрировать".

Единственная польза от этой программы - спрятавшаяся в комментарии еще одна искорка понимания:
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
//получается, что явная специализация включает инстанцирование
Как видите, народ, капля камень точит И здесь понемногу наблюдается какой-то прогресс... Хотя дальше снова пошел поток отсебятины:

Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
2
3
4
//это уже не требуется так как extern объявлению
//достаточно явной специализации
//то есть выходит что явная специализация это явное инстанцироване+
//конкретизирующее определение для конкретного набора типов
И для того, чтобы увидеть, что явная специализация - это обычная функция, которая сразу и безусловно "включает инстанцирование", достаточно было элементарного примера

C++
1
2
template <typename T> void foo(T t) {}
template <> void foo<int>(int i) {}
Объектный файл:

Code
1
0000000000000000 T _Z3fooIiEvT_
https://godbolt.org/z/McMYczGh1
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.08.2023, 16:39
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Нет, не может. Ваш эксперимент "показал", что в ситуации, когда реализация не выдала диагностического сообщения в ответ на ошибочную программу (пользуясь тем, что диагностика таких ошибок не требуется), программа имеет неопределенное поведение.
Что является UB, конкретно, в представленных файлах?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
25.08.2023, 17:24
Цитата Сообщение от IGPIGP Посмотреть сообщение
Что является UB, конкретно, в представленных файлах?
Я уже несколько раз ссылался на это требование стандарта

https://timsong-cpp.github.io/... eneral-5.3

- both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit specialization is reachable from the explicit instantiation.
An implementation is not required to diagnose a violation of this rule ...
Термин "reachable" в данной цитате - нововведение, связанное с появлением поддержки модулей в С++. Если вы не хотите лезть в эти дебри, то можете воспользоваться версией того же требования из С++11

14.7 Template instantiation and specialization [temp.spec]
5 [...]
- both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit instantiation follows a declaration of the explicit specialization.
An implementation is not required to diagnose a violation of this rule.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.08.2023, 18:38
во-первых именно это у меня и есть:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
unless the explicit specialization is reachable from the explicit instantiation
во-вторых explicit instantiation у меня закомментировано вообще. То есть пример (см. комментарии) иллюстрирует тот факт что яв.спец-я полностью замещаяет яв. инстанцирование-опр-е и extern ссылка (яв. инс-е-декларация) вполне нормалльно на него ссылается.
То место в стандарте где указано что инстанцирование происходит после обхявления явной специализации либо неявно либо явно становится совсем мутным, правда. Ведь выходит, что оно происходит прям там и сразу...
Я работал с тех.стандартами и видел много плохого. Но стандарт С++ это что-то.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
25.08.2023, 21:03
Цитата Сообщение от IGPIGP Посмотреть сообщение
во-первых именно это у меня и есть:
Нет, ничего подобного. Explicit instantiation у вас присутствует во втором файле, в строке 4. А явная специализация - в первом. Никакого "reachable" тут нет.

Цитата Сообщение от IGPIGP Посмотреть сообщение
во-вторых explicit instantiation у меня закомментировано вообще.
Нет, не верно. Закомментировано у вас explicit instantiation definition в первом файле. А explicit instantiation declaration во втором у вас присутствует во всей красе. Оно не закомментировано.

Процитированный мною участок стандарта нигде не требует именно explicit instantiation definition для применения этого правила. Там сказано просто explicit instantiation и все. То есть наличие любой формы explicit instantiation активирует это правило.

Стандарт в этом отношении очень педантичен. Если бы речь шла именно о explicit instantiation definition, так бы сказано и было, как, например, в первой части этого же правила.

Цитата Сообщение от IGPIGP Посмотреть сообщение
То есть пример (см. комментарии) иллюстрирует тот факт что яв.спец-я полностью замещаяет яв. инстанцирование-опр-е и extern ссылка (яв. инс-е-декларация) вполне нормалльно на него ссылается.
Нет.

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

Именно такой обман вы и выполнили в своем примере.

И именно по этой причине такие ошибки стандарт заносит в категорию "диагностика не требуется". Простого способа заткнуть эту дыру не существует, то есть недопущение таких ошибок в вашем коде - ваша обязанность. И, разумеется, не надо пытаться специально обмануть компилятор.

Цитата Сообщение от IGPIGP Посмотреть сообщение
То место в стандарте где указано что инстанцирование происходит после обхявления явной специализации либо неявно либо явно становится совсем мутным, правда. Ведь выходит, что оно происходит прям там и сразу...
Ничего там нигде не становится мутным. Просто надо видеть, что именно написано в стандарте, и не выдумывать того, что там не написано.

Добавлено через 22 минуты
---

Более того, даже если мы полностью вычеркнем из стандарта то правило, которое я процитировал выше, ваш код все равно будет ошибочным по другим правилам стандарта языка:

* Если в точке вызова some_template_fn(123); вы намеревались воспользоваться явным инстанцированием, то вы нарушили требования

https://timsong-cpp.github.io/... xplicit#13
13 [...] An entity that is the subject of an explicit instantiation declaration and that is also used in a way that would otherwise cause an implicit instantiation in the translation unit shall be the subject of an explicit instantiation definition somewhere in the program; otherwise the program is ill-formed, no diagnostic required.
А у вас отсутствует explicit instantiation definition - вы его "закомментировали".

* Если же в точке вызова some_template_fn(123); вы намеревались воспользоваться явной специализацией, то вы нарушили требования

https://timsong-cpp.github.io/... xpl.spec#7
7 If a template, a member template or a member of a class template is explicitly specialized, a declaration of that specialization shall be reachable from every 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.
А у вас во втором файле нет объявления явной специализации.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.08.2023, 21:29
Тогда снова получается противоречие. То есть, если раскомментировать explicit instantiation definition, то будет выполнено требование 13 [...]. И если это требуется, то нельзя сказать, что explicit instantiation definition has no effect. Если звёзды зажигают, значит у звёзд есть на что зажигать...
То есть, моей целью и было - показать, что объявления специализации без последующего явного инстанцирования недостаточно, чтобы external definition позволил это слинковать. Но он позволил и я решил, что таки да - has no effect потому как выходит что объявление явной специализации само по себе, содержит в себе инстанциирование. Теперь выходит, что и это не верно согласно букве стандарта. Тогда опять я был прав: опред-е яв.инст-я после яв. полн. спец-ии имеет право на жизнь, потому, что это иной раз просто необходимо. Как в моих файликах. И поэтому стандарт специально оговаривает этот случай.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.08.2023, 21:29

Инстанцирование шаблона для различных типов
Помогите пожалуйста с программой... Нужно создать шаблон класса, для работы со структурой произвольного типа данных. В функции main()...

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

Специализация шаблона
Всем доброго вечера! Возникает непонятная ошибка при создании специализации родового класса cl. В строке 10: template class...

специализация шаблона
начал разбираться с шаблонами. если есть структура, и одна функция именно с int должна работать по особенному, написать можно вот так. ...

Специализация шаблона
Привет, у меня есть вот такой шаблон дерева: template &lt;typename T = int&gt; class Tree{ struct TreeItem{ // элемент дерева ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её. Всё это стресс конечно. Почему?. . .
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru