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[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
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
сигнатура функций-шаблонов.
От: Аноним  
Дата: 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[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.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.