сигнатура функций-шаблонов.
От: Аноним  
Дата: 05.08.03 09:15
Оценка:
В стандарте есть пример, в котором показывается, что для специализаций функций-шаблонов в понятие сигнатуры функции входит сама сигнатура функции (т.е., как я понимаю, типы аргументов (кстати, число аргументов в понятие сигнатуры входит?)), а также аргументы шаблона явно специализированные или неяно выведенные:
//file c1.cpp               //file c2.cpp
template<class T>           template<class T>
void fun(T *);              void fun(T);

void g(int * p)             void h(int * p)
{                           {
   fun(p);                      fun(p);
   //fun<int>(int*)             //fun<int *>(int *)
}                           }


и далее говорится, что все это не нарушает ОДР. Это действительно так, так как сигнатуры разные. Я так понял, что все эти правила для того, чтоб компоновщик нашел правильную функцию, допустим, в таком случае:
//h1.h
template<class T>void fun(T);
template<>void fun(int *); 
//c1.cpp
#include "h1.h"
template<>void fun<int *>(int *)
{
}
//h2.h
template<class T>void fun(T*);
template<>void fun(int *);
//c2.cpp
#include "h2.h"
template<>void fun<int>(int *)
{
}
//somewhere.cpp
#include "h1.h"
void g(int * p)
{
    fun(p);
}

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

Но если есть в заголовке некая
//h.h
template<class T>void fun(T);

и я в двух единицах трансляции вызову
//file c1.cpp               //file c2.cpp
void g(int * p)             void h(int * p)
{                           {
    fun(p);                     fun(p);
}                           }

то, вообще-то, получу две сгенеренных функции с одинаковой сигнатурой (в г++ есть даже опция, которая позволяет сделать этот код ошибочным). Как компилятор борется с такой проблемой? Использованием внутренней компоновки для специализаций?
Re: сигнатура функций-шаблонов.
От: Павел Кузнецов  
Дата: 06.08.03 08:36
Оценка: 18 (4)
Здравствуйте, Вы писали:

> В стандарте есть пример, в котором показывается, что для специализаций функций-шаблонов в понятие

> сигнатуры функции входит сама сигнатура функции (т.е., как я понимаю, типы аргументов (кстати,
> число аргументов в понятие сигнатуры входит?)), а также аргументы шаблона явно специализированные
> или неяно выведенные:

Почти так. Сигнатура специализации шаблона функции состоит из сигнатуры самого шаблона функции
и аргументов шаблона. В сигнатуру собственно шаблона функции входят: сигнатура функции, тип
возвращаемого значения и список параметров шаблона.

>
 //h1.h
> template<class T>void fun(T);
> template<>void fun(int *);
>
> //h2.h
> template<class T>void fun(T*);
> template<>void fun(int *);
>

> Т.е. чтобы компоновщик выбрал правильную функцию, тут как раз часть
> сигнатуры, связанная с аргументами шаблона и пригодится?

Именно так.

> Но если есть в заголовке некая

>
> //h.h
> template<class T>void fun(T);
>

> и я в двух единицах трансляции вызову
>
> //file c1.cpp               //file c2.cpp
> void g(int * p)             void h(int * p)
> {                           {
>     fun(p);                     fun(p);
> }                           }
>

> то, вообще-то, получу две сгенеренных функции с одинаковой сигнатурой

Это зависит от модели порождения специализаций, принятой в компиляторе. Обычно выделяют две
основных: порождать специализации в каждой единице трансляции и предоставлять разбираться
с множественными определениями компоновщику, либо же откладывать инстанциирование до того
момента, когда скомпилированы все единицы трансляции, добавляя в трансляцию шаг между
компиляцией и компоновкой (pre-linker). Например, EDG front end может работать как по первой,
так и по второй модели. В случае первой модели, действительно, будет порождено две специализации.

> (в г++ есть даже опция, которая позволяет сделать этот код ошибочным). Как компилятор

> борется с такой проблемой? Использованием внутренней компоновки для специализаций?

Нет, специализации шаблонов имеют внешнюю компоновку. Однако для специализаций, полученных
в результате инстанциирования шаблонов, обычно используется какой-нибудь дополнительный "флаг",
говорящий компоновщику, что он волен выбирать любое из имеющихся определений. Подобная ситуация
существует и с inline-функциями, по умолчанию имеющими внешнюю компоновку: если подобная функция
не будет подставлена, то для нее будет порождено такое же "тело", как и для обычных функций,
с той только разницей, что inline-функции могут быть определены в нескольких единицах трансляции,
и компоновщику, также как и со специализациями, нужно будет выбрать одно из этих определений.
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: сигнатура функций-шаблонов.
От: Lorenzo_LAMAS  
Дата: 06.08.03 08:55
Оценка:
Здравствуйте, Павел

ПК>Это зависит от модели порождения специализаций, принятой в компиляторе. Обычно выделяют две

ПК>основных: порождать специализации в каждой единице трансляции и предоставлять разбираться
ПК>с множественными определениями компоновщику, либо же откладывать инстанциирование до того
ПК>момента, когда скомпилированы все единицы трансляции, добавляя в трансляцию шаг между
ПК>компиляцией и компоновкой (pre-linker). Например, EDG front end может работать как по первой,
ПК>так и по второй модели. В случае первой модели, действительно, будет порождено две специализации.


Нельзя ли чуть поподробнее о второй модели. Т.е. в таком случае множественные определения не генерятся? Т.е. компилятор грубо говоря имеет список необходимых специализаций и он их генерит, создавая специальную/ые единицу/цы (кажется, единицы инстанцирования — так в стандарте) и потом компоновщик разрешает все ссылки?

ПК>Нет, специализации шаблонов имеют внешнюю компоновку. Однако для специализаций, полученных

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

Вообще говоря, представлений о внутренней компоновке я набрался из Липмана (Inside C++ object model )может так когда-то в с-фронте было? Он говорил такое и про инлайн функции (в частности, про генерируемые компилятором нетривиальные конструкторы)

Павел, а чтобы такое по этому поводу почитать?
Of course, the code must be complete enough to compile and link.
Re[3]: сигнатура функций-шаблонов.
От: Павел Кузнецов  
Дата: 07.08.03 16:16
Оценка: 2 (1)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

ПК>> Это зависит от модели порождения специализаций, принятой в

ПК>> компиляторе. Обычно выделяют две основных <...>

LL> Нельзя ли чуть поподробнее о второй модели


<...>

LL> Павел, а чтобы такое по этому поводу почитать?


А вот это запросто Книга (не уверен, что есть в переводе):

David Vandevoorde & Nicolai Josuttis. C++ Templates: The Complete Guide

Учитывая, что Vandevoorde является как раз тем, кто реализовывал экспорт шаблонов в EDG...
Tакже можно поискать сообщения Дэвида в comp.std.c++ и comp.lang.c++.moderated, в некоторых
он вполне подробно освещает детали реализации шаблонов в EDG front end, поддерживающем в том
числе и упомянутую модель с пре-компоновкой.
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.