Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.01.23 18:21
Оценка:
У меня есть функции, реализации которых нужны для разных комбинаций Unicode и ANSI (Unicode/Unicode, ANSI/ANSI, Unicode/ANSI). Строки ANSI используются только в качестве источников (байт дополняется нулевым старшим). Реализации отличаются только используемыми типами. Напрашивается идея оформить их одним шаблоном, но получается затык с "перекрестными" версиями — обычное присваивание из char в wchar_t расширяет знак, а мне нужно расширять нулем.

Если добавить в список параметров шаблона, кроме типов символов источника/результата, еще и третий промежуточный тип для беззнакового char, компилятор не в состоянии вывести его только по параметрам функции. Даже если делаю отдельную функцию ConvertChar, комбинация параметров шаблона все равно однозначно невыводима из комбинации параметров/результатов функций, хотя остальные комбинации, кроме трех основных, не используются. Но добавлять явные параметры шаблона в вызовы функций нельзя — они должны выглядеть, как обычные функции, вызывающий код ничего не знает про их шаблоны.

Как принято бороться с такими проявлениями противоестественного интеллекта?
Re: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char?
От: Videoman Россия https://hts.tv/
Дата: 19.01.23 18:25
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Как принято бороться с такими проявлениями противоестественного интеллекта?


Приведи пример кода где проблема?
Re[2]: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.01.23 18:41
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Приведи пример кода где проблема?


А что непонятно из описания?

template <typename DstType, typename SrcType, typename IntType>
void s (DstType * Dst, SrcType const * Src) {

  *Dst = static_cast <IntType> (*Src);

}

template void s <wchar_t, wchar_t, wchar_t> (wchar_t *, wchar_t const *);
template void s <char, char, char> (char *, char const *);
template void s <wchar_t, char, unsigned char> (wchar_t *, char const *);

void f () {

  wchar_t * W;
  char * C;

  s (W, W);
  s (C, C);
  s (W, C);

}
Re[3]: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char
От: Videoman Россия https://hts.tv/
Дата: 19.01.23 19:18
Оценка: 18 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>А что непонятно из описания?


Да потому-что фиг проссышь, что ты имеешь в виду. Научись задание формулировать четко и однозначно. Это ты хочешь ?:
template <typename dst_t, typename src_t>
struct s_trait_t;
template <>
struct s_trait_t<wchar_t, wchar_t>
{
    using type = wchar_t;
};
template <>
struct s_trait_t<char, char>
{
    using type = char;
};
template <>
struct s_trait_t<wchar_t, char>
{
    using type = unsigned char;
};


template <typename DstType, typename SrcType>
void s (DstType * Dst, SrcType const * Src) 
{
    using IntType = typename s_trait_t<DstType, SrcType>::type;

    *Dst = static_cast <IntType> (*Src);

}

template void s <wchar_t, wchar_t> (wchar_t *, wchar_t const *);
template void s <char, char> (char *, char const *);
template void s <wchar_t, char> (wchar_t *, char const *);

void f () {

  wchar_t * W;
  char * C;

  s (W, W);
  s (C, C);
  s (W, C);

}

int main()
{
  f();
}
Re[4]: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.01.23 19:30
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Да потому-что фиг проссышь, что ты имеешь в виду. Научись задание формулировать четко и однозначно.


Так чего именно не хватает в описании из того, что видно по коду?

V>struct s_trait_t;


Без этого костыля никак?
Re[5]: Можно ли сделать универсальный шаблон для разных комб
От: Videoman Россия https://hts.tv/
Дата: 19.01.23 19:53
Оценка: 18 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Так чего именно не хватает в описании из того, что видно по коду?


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

V>>struct s_trait_t;


ЕМ>Без этого костыля никак?


Может так ?:
#include <type_traits>

template <typename DstType, typename SrcType>
void s (DstType * Dst, SrcType const * Src) 
{
    using IntType = typename std::make_unsigned<SrcType>::type;

    *Dst = static_cast<DstType>(static_cast<IntType>(*Src));

}

void f () {

  wchar_t * W;
  char * C;

  s (W, W);
  s (C, C);
  s (W, C);

}

int main()
{
  f();
}
Отредактировано 19.01.2023 20:35 Videoman . Предыдущая версия .
Re[6]: Можно ли сделать универсальный шаблон для разных комб
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.01.23 21:20
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Из описания замучаешься восстанавливать не работающий код.


В каком смысле "не работающий код"? Код здесь вообще ни при чем — проблема в том, что комбинация параметров шаблона (если в них явно добавлять промежуточный тип) не может быть однозначно выведена из комбинации параметров функции и ее возвращаемого типа. Получается, что решить можно только с костылями — хоть явными, хоть библиотечными. Придется их использовать.
Re[7]: Можно ли сделать универсальный шаблон для разных комб
От: Videoman Россия https://hts.tv/
Дата: 19.01.23 21:42
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

V>>Из описания замучаешься восстанавливать не работающий код.


ЕМ>В каком смысле "не работающий код"?

Ну тебе понятно что ты хочешь, а из твоей постановки мне, например, не понятно. С кодом быстрее, точнее и быстрее.

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

Естественно выводы типов делаются только для сигнатуры функции и только для типов которые в ней используются. Если уж тебе прям так хочется сделать промежуточный тип как параметр шаблона, сделай так:
template <typename DstType, typename SrcType, typename IntType = typename std::make_unsigned<SrcType>::type>
void s (DstType * Dst, SrcType const * Src) 
{
    *Dst = static_cast<DstType>(static_cast<IntType>(*Src));
}
Мне трудно судить о твоих вкусах.

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

Получается, что компилятор несовершенен, и не обязан компилировать весь метод, который может быть ого-го, только для того, что бы вывести типы и понять какую функцию подставлять при вызове. Тело-то может быть и в другом месте, теоретически, определено. Всё тоже самое что и со стандартным Си.
Re: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char?
От: пффф  
Дата: 19.01.23 21:48
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>У меня есть функции, реализации которых нужны для разных комбинаций Unicode и ANSI (Unicode/Unicode, ANSI/ANSI, Unicode/ANSI). Строки ANSI используются только в качестве источников (байт дополняется нулевым старшим). Реализации отличаются только используемыми типами. Напрашивается идея оформить их одним шаблоном, но получается затык с "перекрестными" версиями — обычное присваивание из char в wchar_t расширяет знак, а мне нужно расширять нулем.


Не понял, а в чем проблема расширять через промежуточный каст в unsigned char?
Re[2]: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char
От: Videoman Россия https://hts.tv/
Дата: 19.01.23 21:58
Оценка:
Здравствуйте, пффф, Вы писали:

П>Не понял, а в чем проблема расширять через промежуточный каст в unsigned char?


Он же обобщенный код хочет. А промежуточный каст wchar_t к unsigned char, это уже обрезание получается.
Re[3]: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char
От: пффф  
Дата: 19.01.23 22:14
Оценка:
Здравствуйте, Videoman, Вы писали:

П>>Не понял, а в чем проблема расширять через промежуточный каст в unsigned char?


V>Он же обобщенный код хочет. А промежуточный каст wchar_t к unsigned char, это уже обрезание получается.


У него проблема с расширением char в wchar_t, наоборот — никаких проблем не должно быть.

А обобщенный код можно написать с использованием библиотечных "костылей" типа std::make_unsigned
Re[7]: Можно ли сделать универсальный шаблон для разных комб
От: rg45 СССР  
Дата: 20.01.23 09:38
Оценка: 18 (1) +2
Здравствуйте, Евгений Музыченко, Вы писали:

V>>Из описания замучаешься восстанавливать не работающий код.


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


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

Например, можно было бы сформулировать правило таким образом: "когда тип назначения (Dst) больше по рамеру, чем исходный тип (Src), выполнить промежуточное преобразование Src к беззнаковому типу, во всех остальных случаях промежуточный тип совпадает с Src". При такой формулировке, утилиту преобразования типов, предложенную здесь
Автор: Videoman
Дата: 19.01.23
, можно было бы переписать более универсально:

template <typename dst_t, typename src_t, typename = void>
struct s_trait_t
{
    using type = src_t;
};

template <typename dst_t, typename src_t>
struct s_trait_t<dst_t, src_t, std::enable_if_t<(sizeof(dst_t) > sizeof(src_t))>>
{
    using type = std::make_unsigned_t<src_t>;
};


Вообще, самых разных реализаций здесь можно придумать вагон и маленькую тележку, но все только в зависимости от ТВОИХ требований.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 20.01.2023 10:12 rg45 . Предыдущая версия . Еще …
Отредактировано 20.01.2023 10:08 rg45 . Предыдущая версия .
Re[8]: Можно ли сделать универсальный шаблон для разных комб
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.01.23 10:25
Оценка:
Здравствуйте, rg45, Вы писали:

R>костыльным предложенное решение тебе видится только лишь потому, что ты не смог, или просто не удосужился, эти правила сформулировать.


Я уже много раз писал, что считаю "костыльными" любые решения, основанные на побочных эффектах использования шаблонов, хотя они давно стали нормой и освящены с самых высоких позиций. У меня нет проблем с формулировкой правил, а вот возможности довести их непосредственно до компилятора у меня нет — только путем влияния на его работу косвенно, через задницу. Но что ж делать — за неимением гербовой придется писать на клозетной.
Re[9]: Можно ли сделать универсальный шаблон для разных комб
От: rg45 СССР  
Дата: 20.01.23 10:31
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:


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


И тебе не раз отвечали: считай что угодно, на здоровье.

ЕМ>У меня нет проблем с формулировкой правил,


Только, как минимум, уже двое человек не смогли понять, чего ты хочешь.

ЕМ>а вот возможности довести их непосредственно до компилятора у меня нет — только путем влияния на его работу косвенно, через задницу.


И опять все наоборот — у тебя есть возможность донести до компилятора многое, и тебе привели примеры, как это сделать.

ЕМ>Но что ж делать — за неимением гербовой придется писать на клозетной.


Я не пойму, зачем тебе этот плохой язык. Тебя принуждают его использовать?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[10]: Можно ли сделать универсальный шаблон для разных комб
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.01.23 10:56
Оценка:
Здравствуйте, rg45, Вы писали:

R>как минимум, уже двое человек не смогли понять, чего ты хочешь.


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

R>у тебя есть возможность донести до компилятора многое, и тебе привели примеры, как это сделать.


Еще раз: "довести до компилятора" — это объяснить нужные правила непосредственно ему. Когда для типа указывается модификатор unsigned или const, для числа — суффикс "длинное", для строки — префикс "широкая", то это оно самое. Когда используются побочные эффекты механизма, придуманного совсем для другого, просто потому, что "это работает" — это костыль. И очень удручает, что парадигма языка, предостерегая от чрезмерного использования побочных эффектов в "базовом" наборе функций, столь же чрезмерно поощряет это в шаблонном механизме, лишая язык более адекватных способов управления компиляцией.

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


Покажите мне другой язык, на котором можно делать драйверы ядра для Windows, в котором накладные расходы не превышают микросекунд — я рассмотрю.
Re[11]: Можно ли сделать универсальный шаблон для разных ком
От: Videoman Россия https://hts.tv/
Дата: 20.01.23 13:49
Оценка: +2
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Еще раз: "довести до компилятора" — это объяснить нужные правила непосредственно ему. Когда для типа указывается модификатор unsigned или const, для числа — суффикс "длинное", для строки — префикс "широкая", то это оно самое. Когда используются побочные эффекты механизма, придуманного совсем для другого, просто потому, что "это работает" — это костыль. И очень удручает, что парадигма языка, предостерегая от чрезмерного использования побочных эффектов в "базовом" наборе функций, столь же чрезмерно поощряет это в шаблонном механизме, лишая язык более адекватных способов управления компиляцией.


Я написал на "побочке", так как ты не соизволил сообщить какую версию компилятора С++ используешь. Из опыта общения предположил, что самую самую древнюю, которая еще как-то работает. В современном С++ для всего этого есть Concept-ы, где все уже пишется на адекватном, специально приспособленном для этого языке, всё как ты хочешь. В любом случае, так как ты работаешь с типами, это будет вызов мета-функции, хоть здесь, хоть там.
Отредактировано 20.01.2023 14:17 Videoman . Предыдущая версия .
Re: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char?
От: Sm0ke Россия ksi
Дата: 20.01.23 17:36
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>У меня есть функции, реализации которых нужны для разных комбинаций Unicode и ANSI (Unicode/Unicode, ANSI/ANSI, Unicode/ANSI). Строки ANSI используются только в качестве источников (байт дополняется нулевым старшим). Реализации отличаются только используемыми типами. Напрашивается идея оформить их одним шаблоном, но получается затык с "перекрестными" версиями — обычное присваивание из char в wchar_t расширяет знак, а мне нужно расширять нулем.


ЕМ>Если добавить в список параметров шаблона, кроме типов символов источника/результата, еще и третий промежуточный тип для беззнакового char, компилятор не в состоянии вывести его только по параметрам функции. Даже если делаю отдельную функцию ConvertChar, комбинация параметров шаблона все равно однозначно невыводима из комбинации параметров/результатов функций, хотя остальные комбинации, кроме трех основных, не используются. Но добавлять явные параметры шаблона в вызовы функций нельзя — они должны выглядеть, как обычные функции, вызывающий код ничего не знает про их шаблоны.


ЕМ>Как принято бороться с такими проявлениями противоестественного интеллекта?


// function
{
if constexpr( std::is_signed_v<T> ) {}
else {}
}

Это поможет?
Re[9]: Можно ли сделать универсальный шаблон для разных комб
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 20.01.23 18:10
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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


Причем тут SFINAE? Его, кстати, гораздо меньше в современных плюсах используют, потому что доработали язык. Но тебе не хочется изучать современный C++, гораздо проще скопом всё обозвать костылями
Маньяк Робокряк колесит по городу
Re[12]: Можно ли сделать универсальный шаблон для разных ком
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 21.01.23 12:49
Оценка:
Здравствуйте, Videoman, Вы писали:

V>В современном С++ для всего этого есть Concept-ы, где все уже пишется на адекватном, специально приспособленном для этого языке


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

M>Причем тут SFINAE? Его, кстати, гораздо меньше в современных плюсах используют, потому что доработали язык.


Да, с опозданием лет на двадцать.

M>Но тебе не хочется изучать современный C++, гораздо проще скопом всё обозвать костылями


Изучать мне как раз хочется, но проблема в том, что в моей основной области (драйверы ядра под винду) в нагрузку к "современному C++" идет неадекватно тормозная студия вкупе с ограниченной совместимостью.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.