#cpp #шаблоны_с++ #компиляция #линковка
Каким образом линкер решает проблему с ODR для шаблонов? Ведь в каждом translation unit у нас должна быть инстанциация шаблона (т.е. в каждом объектном файле, который линкер должен собрать).
Ответы
Ответ 1
Для шаблонов нет никакой "проблемы с ODR". ODR также работает и для шаблонов: 6.2 One-definition rule 1. No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template. т.е. в одной единице трансляции не может быть нескольких определений шаблона: templatestruct Some {}; template struct Some {};//Ошибка Что касается определений в разных единицах трансляции (не только шаблоны), то они могут появляться, если удовлетворяют ряду требований. There can be more than one definition of a class type (Clause 10), enumeration type (9.6), inline function with external linkage (9.1.6), inline variable with external linkage (9.1.6), class template (Clause 12), non-static function template (12.6.6), concept (12.6.8), static data member of a class template (12.6.1.3), member function of a class template (12.6.1.1), or template specialization for which some template parameters are not specified (12.8, 12.6.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then список требований, который вряд ли имеет смысл приводить в данном ответе, т.к. предполагаем, что шаблон им всем удовлетворяет If D is a template and is defined in more than one translation unit, then the preceding requirements shall apply both to names from the template’s enclosing scope used in the template definition (12.7.3), and also to dependent names at the point of instantiation (12.7.2). If the definitions of D satisfy all these requirements, then the behavior is as if there were a single definition of D. [Note: The entity is still declared in multiple translation units, and 6.5 still applies to these declarations. In particular, lambda-expressions (7.5.5) appearing in the type of D may result in the different declarations having distinct types. — end note] If the definitions of D do not satisfy these requirements, then the behavior is undefined. т.е. при множественном определении шаблона в разных единицах трансляции поведение такое же, как если бы определение было всего одно. Как конкретно это будет делать реализация стандарт не уточняет. В C++ используется декорирование имен (name mangling, name decoration), поэтому при инстанцировании шаблона с заданным набором аргументов, имена полученных определений будут искажены. Одинаковые имена этих определений будут указывать на то, что это повторяющееся определение, полученное при инстанцировании шаблона, соответственно линковщик в праве оставить лишь одно из них, удалив всё лишнее.
Комментариев нет:
Отправить комментарий