Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.01.23 13:32
Оценка: :)
Хотел в одной из библиотек сделать финт ушами: в заголовке оставить объявления нескольких одноименных функций с перегрузкой типов параметров, а в модуле реализовать их общим шаблоном, явно определив версии с допустимыми комбинациями параметров. По замыслу, это позволило бы линковать с ней другие библиотеки без перекомпиляции их исходников. Но оказалось, что [как минимум] VC++ дает шаблонным функциям сигнатуры, отличные от сигнатур обычных функций, и линковки таки не получается.

Какой в этом может быть смысл? Чем функция с определенными типами параметров и результата, реализованная через шаблон, в плане линковки отличается от функции с теми же типами, но без шаблона?
Re: Для чего шаблонной функции нужна особая сигнатура?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 21.01.23 13:37
Оценка: 1 (1) +3
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Какой в этом может быть смысл? Чем функция с определенными типами параметров и результата, реализованная через шаблон, в плане линковки отличается от функции с теми же типами, но без шаблона?


Ну, нешаблонная функция имеет приоритет перед шаблонной, может, для этого?


ЗЫ А вообще, ты — смешной. Костеришь использование побочных эффектов шаблонов, хотя это давно стало стандартом, и всё давно разжевано уже донельзя, а сам какие-то хаки пытаешься изобрести
Маньяк Робокряк колесит по городу
Отредактировано 21.01.2023 13:40 Marty . Предыдущая версия .
Re[2]: Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.01.23 13:48
Оценка:
Здравствуйте, Marty, Вы писали:

M>Костеришь использование побочных эффектов шаблонов, хотя это давно стало стандартом, и всё давно разжевано уже донельзя


Ну вот в тех же исламских странах ношение хиджаба и прочих причиндалов стало стандартом на несколько тысяч лет раньше, и тоже "давно разжевано уже донельзя" — значит, следует перестать это костерить и начать приветствовать?

А в Китае лишь сравнительно недавно перестали бинтовать ступни маленьким девочкам. Если бы этот обычай никто не костерил — думаешь, все равно перестали бы?
Re[3]: Для чего шаблонной функции нужна особая сигнатура?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 21.01.23 13:58
Оценка: -2 :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ну вот в тех же исламских странах ношение хиджаба и прочих причиндалов стало стандартом на несколько тысяч лет раньше, и тоже "давно разжевано уже донельзя" — значит, следует перестать это костерить и начать приветствовать?


ЕМ>А в Китае лишь сравнительно недавно перестали бинтовать ступни маленьким девочкам. Если бы этот обычай никто не костерил — думаешь, все равно перестали бы?


Ну, а ты придумал какой-то расширитель анального отверстия, и жалуешься, что тебе почему-то больно. А так смотри, может ещё кому-нибудь бы понравилось, и все стали бы себе жопку расширять, и вошло бы в традиции на тысячелетия. Но тебя это не парит, тебя хиджабы волнуют. А что, зато запоры не мучают
Маньяк Робокряк колесит по городу
Re: Для чего шаблонной функции нужна особая сигнатура?
От: so5team https://stiffstream.com
Дата: 23.01.23 05:24
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Хотел в одной из библиотек сделать финт ушами: в заголовке оставить объявления нескольких одноименных функций с перегрузкой типов параметров, а в модуле реализовать их общим шаблоном, явно определив версии с допустимыми комбинациями параметров. По замыслу, это позволило бы линковать с ней другие библиотеки без перекомпиляции их исходников. Но оказалось, что [как минимум] VC++ дает шаблонным функциям сигнатуры, отличные от сигнатур обычных функций, и линковки таки не получается.


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

// dummy.hpp-файл.
#pragma once

void dummy(char, unsigned int);
void dummy(unsigned int, float);
void dummy(float, unsigned long);

// dummy.cpp файл.
#include "dummy.hpp"

template<typename A, typename B>
void dummy_impl(A a, B b) {...}

void dummy(char a, unsigned int b) { dummy_impl(a, b); }
void dummy(unsigned int a, float b) { dummy_impl(a, b); }
void dummy(float a, unsigned long b) { dummy_impl(a, b); }


?
Отредактировано 23.01.2023 5:57 so5team . Предыдущая версия .
Re[2]: Для чего шаблонной функции нужна особая сигнатура?
От: K13 http://akvis.com
Дата: 23.01.23 07:41
Оценка: +1
Здравствуйте, so5team, Вы писали:

S>Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ>>Хотел в одной из библиотек сделать финт ушами: в заголовке оставить объявления нескольких одноименных функций с перегрузкой типов параметров, а в модуле реализовать их общим шаблоном, явно определив версии с допустимыми комбинациями параметров. По замыслу, это позволило бы линковать с ней другие библиотеки без перекомпиляции их исходников. Но оказалось, что [как минимум] VC++ дает шаблонным функциям сигнатуры, отличные от сигнатур обычных функций, и линковки таки не получается.


S>Простите, но как было сказано в другой теме, без примеров кода однозначно понять что же вам нужно бывает затруднительно. Вы говорите вот о такой ситуации:


S>
S>// dummy.hpp-файл.
S>#pragma once

S>void dummy(char, unsigned int);
S>void dummy(unsigned int, float);
S>void dummy(float, unsigned long);

S>// dummy.cpp файл.
S>#include "dummy.hpp"

S>template<typename A, typename B>
S>void dummy_impl(A a, B b) {...}

S>void dummy(char a, unsigned int b) { dummy_impl(a, b); }
S>void dummy(unsigned int a, float b) { dummy_impl(a, b); }
S>void dummy(float a, unsigned long b) { dummy_impl(a, b); }
S>


S>?


как я понял, он хочет просто написать шаблон dummy(), явно инстанцировать нужные комбинации и всё.
без прокидывания вызова.
Re[3]: Для чего шаблонной функции нужна особая сигнатура?
От: so5team https://stiffstream.com
Дата: 23.01.23 07:44
Оценка:
Здравствуйте, K13, Вы писали:

K13>как я понял, он хочет просто написать шаблон dummy(), явно инстанцировать нужные комбинации и всё.

K13>без прокидывания вызова.

У меня была и такая версия, но в формулировке Евгения не было термина "инстанциирование", который здесь явно напрашивался и не позволил бы трактовать условие задачи иначе. Поэтому и решил уточнить с примером кода, для устранения разночтений.
Re[2]: Для чего шаблонной функции нужна особая сигнатура?
От: Videoman Россия https://hts.tv/
Дата: 23.01.23 08:28
Оценка:
Здравствуйте, so5team, Вы писали:

S>Здравствуйте, Евгений Музыченко, Вы писали:


S>Простите, но как было сказано в другой теме, без примеров кода однозначно понять что же вам нужно бывает затруднительно. Вы говорите вот о такой ситуации...


Как я понял, он спрашивает почему, когда он делает полную специализацию шаблонной функции, её манглинг не превращается в полностью такой же как у простой функции с такими же параметрами и её нельзя вызвать из Cи.
Ответ очевиден: потому-что это другая функция и для вызова из Си нужны обертки.
Re[2]: Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.01.23 09:28
Оценка:
Здравствуйте, so5team, Вы писали:

S>без примеров кода однозначно понять что же вам нужно бывает затруднительно


В данном случае то, что мне нужно — отдельный вопрос. Основной вопрос был о том, для чего сигнатура шаблонной функции отличается от сигнатуры перегруженной функции с той же комбинацией типов. Один из вариантов — для обеспечения приоритета. Еще могут быть какие-то основания?
Re[4]: Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.01.23 09:37
Оценка:
Здравствуйте, so5team, Вы писали:

S>в формулировке Евгения не было термина "инстанциирование"


Там было конкретное описание действия: "явно определив версии с допустимыми комбинациями параметров". "Инстанцирование" — это не термин, а уродливая калька для тех, кто мыслит не понятиями, а идентификаторами. Если же мыслить понятиями, то как еще можно понять выражение "явно определив версии", кроме как "instantiating"? Что еще можно сделать с шаблоном функции, чтобы "явно определить" его версии?
Отредактировано 23.01.2023 9:38 Евгений Музыченко . Предыдущая версия .
Re[3]: Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.01.23 09:38
Оценка:
Здравствуйте, Videoman, Вы писали:

V>и её нельзя вызвать из Cи.


Разве я где-то упоминал Си?
Re[3]: Для чего шаблонной функции нужна особая сигнатура?
От: so5team https://stiffstream.com
Дата: 23.01.23 09:51
Оценка: 1 (1) +1
Здравствуйте, Евгений Музыченко, Вы писали:

S>>без примеров кода однозначно понять что же вам нужно бывает затруднительно


ЕМ>В данном случае то, что мне нужно — отдельный вопрос.


Евгений, на мой взгляд обязательная предпосылка к конструктивному диалогу -- это уважение к вопросам оппонентов. Я задал уточняющий вопрос, был бы очень признателен вам, если бы вы нашли возможность на него ответить. Это позволит мне (и, возможно, не только мне) лучше понять вас, т.к. ваша формулировка, очевидно, вызывает разночтения и допускает несколько толкований.

ЕМ>Основной вопрос был о том, для чего сигнатура шаблонной функции отличается


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

PS. При этом я могу сильно ошибаться и в стандарте C++ все это может быть описано сильно другими словами, но такой взгляд на вещи сильно упрощает жизнь с C++.
Re[5]: Для чего шаблонной функции нужна особая сигнатура?
От: so5team https://stiffstream.com
Дата: 23.01.23 10:00
Оценка: 1 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Там было конкретное описание действия: "явно определив версии с допустимыми комбинациями параметров".


Определить версии с допустимыми комбинациями параметров можно по-разному:
template<typename A, typename B>
void dummy(A a, B b) {
  static_assert((std::is_same_v<A, char> && std::is_same_v<B, int>)
    || (std::is_same_v<A, int> && std::is_same_v<B, float>)
    || (std::is_same_v<A, float> && std::is_same_v<B, long long>));

  ...
}

или
template<typename A, typename B>
void dummy(A a, B b);

template<>
void dummy(char a, int b) {...}

template<>
void dummy(int a, float b) {...}

template<>
void dummy(float a, long long b) {...}


ЕМ>"Инстанцирование" — это не термин, а уродливая калька для тех, кто мыслит не понятиями, а идентификаторами.


"Инстанцииорование" и "специализация" -- это вполне себе конкретные понятия, которые обозначают конкретные вещи. Часть общего словаря, на котором С++ разработчики доносят свои идеи до коллег. Использование устоявшихся терминов устраняет неоднозначности в толкованиях.
Re[3]: Для чего шаблонной функции нужна особая сигнатура?
От: Videoman Россия https://hts.tv/
Дата: 23.01.23 10:03
Оценка: 18 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>В данном случае то, что мне нужно — отдельный вопрос. Основной вопрос был о том, для чего сигнатура шаблонной функции отличается от сигнатуры перегруженной функции с той же комбинацией типов. Один из вариантов — для обеспечения приоритета. Еще могут быть какие-то основания?


Потому, что даже если мы имеем шаблон функции:
template <typename type_t>
void fun(const type_t* ptr)
{
// ...
}
то, вот это вот разные функции:
void fun(const char* ptr); // 1
template <>
void fun(const char* ptr); // 2

// ...

const char* ptr = "some string";

fun(ptr); // вызываем первую, у неё приоритет
fun<>(ptr); // вызываем вторую, явно указывая что хотим специализацию шаблона
Re[4]: Для чего шаблонной функции нужна особая сигнатура?
От: so5team https://stiffstream.com
Дата: 23.01.23 10:13
Оценка:
Здравствуйте, Videoman, Вы писали:

V>[/ccode]то, вот это вот разные функции:
V>fun(ptr); // вызываем первую, у неё приоритет
V>fun<>(ptr); // вызываем вторую, явно указывая что хотим специализацию шаблона
V>


Его волнует проблема линковки:

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

К линковке приоритет выбора между шаблоном и обычной функцией не имеет отношения. Зато линкеру нужно повыбрасывать копии реализации шаблона функции с одинаковыми параметрами, созданными в разных единицах трансляции, а оставить только одну.
Re[3]: Для чего шаблонной функции нужна особая сигнатура?
От: σ  
Дата: 23.01.23 10:21
Оценка: +2
ЕМ>В данном случае то, что мне нужно — отдельный вопрос. Основной вопрос был о том, для чего сигнатура шаблонной функции отличается от сигнатуры перегруженной функции с той же комбинацией типов. Один из вариантов — для обеспечения приоритета. Еще могут быть какие-то основания?

Очевидно, для того, чтобы различать функции с одинаковым типом, но инстанциированные из разных шаблонов
template<typename T, typename U> void f(T, U); // 1
template<typename U, typename T> void f(T, U); // 2


int main()
{
    f<int, double>(0, 0.); // 1
    f<double, int>(0, 0.); // 2
}

(https://timsong-cpp.github.io/cppwp/n4659/temp.over.link#1)
Отредактировано 23.01.2023 13:01 σ . Предыдущая версия .
Re[4]: Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.01.23 10:26
Оценка:
Здравствуйте, so5team, Вы писали:

S>Я задал уточняющий вопрос, был бы очень признателен вам, если бы вы нашли возможность на него ответить.


Да, в целом Ваше предположение верно — я хочу оставить в заголовке только перегруженные объявления, а шаблон спрятать в файл реализации (.cpp), поскольку так проще всего ограничить количество возможных вариантов, и не нарушать совместимости с другими библиотеками.

Увы, меня всегда раздражает стремление свести обсуждение понятий и смыслов к обмену формулами или фрагментами кода, если речи не идет о синтаксисе, особенностях семантики и подобных вещах, где код является ключевым.

S>в моей вселенной нет сигнатуры "шаблонной функции", как и нет такой штуки, как "шаблонная функция". А есть "шаблон функции"


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

S>не функция, а некий шаблон


Или функция, которая является шаблонной — типовой, применимой к различным конкретным условиям.

S>если нет функции, то нет и сигнатуры.


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

S>в стандарте C++ все это может быть описано сильно другими словами


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

Но, зная, что есть люди, которым доставляет удовольствие чтение и обсуждение стандартов C++, не упускаю случая дать им возможность проявить себя.
Re[5]: Для чего шаблонной функции нужна особая сигнатура?
От: σ  
Дата: 23.01.23 10:39
Оценка: +1
ЕМ>Это достаточно странно, поскольку и в англоязычной, и в русскоязычной литературе термины "шаблон функции" и "шаблонная функция" вполне себе равнозначны, то же справедливо и для классов.

«function template» и «templated function» это-таки не одно и то же
Re[6]: Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.01.23 10:41
Оценка:
Здравствуйте, so5team, Вы писали:

S>Определить версии с допустимыми комбинациями параметров можно по-разному


При этом для шаблонной функции можно получить сигнатуру, совпадающую с сигнатурой нешаблонной, с той же комбинацией? Если нет, то какое это имеет значение для заданного вопроса?

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


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

"Специализация" — гораздо более давно устоявшийся термин для многих смыслов, он и к шаблонам подошел удачно.
Re[5]: Для чего шаблонной функции нужна особая сигнатура?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.01.23 10:45
Оценка:
Здравствуйте, so5team, Вы писали:

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


Это обычно делается за счет того же механизма, который выбрасывает одинаковые константы (строки, GUID'ы/UUID'ы и т.п.), отдельных средств для этого не требуется. У MS для этого создается COMDAT.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.