У меня есть функции, реализации которых нужны для разных комбинаций Unicode и ANSI (Unicode/Unicode, ANSI/ANSI, Unicode/ANSI). Строки ANSI используются только в качестве источников (байт дополняется нулевым старшим). Реализации отличаются только используемыми типами. Напрашивается идея оформить их одним шаблоном, но получается затык с "перекрестными" версиями — обычное присваивание из char в wchar_t расширяет знак, а мне нужно расширять нулем.
Если добавить в список параметров шаблона, кроме типов символов источника/результата, еще и третий промежуточный тип для беззнакового char, компилятор не в состоянии вывести его только по параметрам функции. Даже если делаю отдельную функцию ConvertChar, комбинация параметров шаблона все равно однозначно невыводима из комбинации параметров/результатов функций, хотя остальные комбинации, кроме трех основных, не используются. Но добавлять явные параметры шаблона в вызовы функций нельзя — они должны выглядеть, как обычные функции, вызывающий код ничего не знает про их шаблоны.
Как принято бороться с такими проявлениями противоестественного интеллекта?
Re: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Так чего именно не хватает в описании из того, что видно по коду?
Из описания замучаешься восстанавливать не работающий код. Куча вариантов может быть, тебе не очевидных.
V>>struct s_trait_t;
ЕМ>Без этого костыля никак?
Здравствуйте, Videoman, Вы писали:
V>Из описания замучаешься восстанавливать не работающий код.
В каком смысле "не работающий код"? Код здесь вообще ни при чем — проблема в том, что комбинация параметров шаблона (если в них явно добавлять промежуточный тип) не может быть однозначно выведена из комбинации параметров функции и ее возвращаемого типа. Получается, что решить можно только с костылями — хоть явными, хоть библиотечными. Придется их использовать.
Re[7]: Можно ли сделать универсальный шаблон для разных комб
Здравствуйте, Евгений Музыченко, Вы писали:
V>>Из описания замучаешься восстанавливать не работающий код.
ЕМ>В каком смысле "не работающий код"?
Ну тебе понятно что ты хочешь, а из твоей постановки мне, например, не понятно. С кодом быстрее, точнее и быстрее.
ЕМ>Код здесь вообще ни при чем — проблема в том, что комбинация параметров шаблона (если в них явно добавлять промежуточный тип) не может быть однозначно выведена из комбинации параметров функции и ее возвращаемого типа.
Естественно выводы типов делаются только для сигнатуры функции и только для типов которые в ней используются. Если уж тебе прям так хочется сделать промежуточный тип как параметр шаблона, сделай так:
Мне трудно судить о твоих вкусах.
ЕМ>Получается, что решить можно только с костылями — хоть явными, хоть библиотечными. Придется их использовать.
Получается, что компилятор несовершенен, и не обязан компилировать весь метод, который может быть ого-го, только для того, что бы вывести типы и понять какую функцию подставлять при вызове. Тело-то может быть и в другом месте, теоретически, определено. Всё тоже самое что и со стандартным Си.
Re: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>У меня есть функции, реализации которых нужны для разных комбинаций Unicode и ANSI (Unicode/Unicode, ANSI/ANSI, Unicode/ANSI). Строки ANSI используются только в качестве источников (байт дополняется нулевым старшим). Реализации отличаются только используемыми типами. Напрашивается идея оформить их одним шаблоном, но получается затык с "перекрестными" версиями — обычное присваивание из char в wchar_t расширяет знак, а мне нужно расширять нулем.
Не понял, а в чем проблема расширять через промежуточный каст в unsigned char?
Re[2]: Можно ли сделать универсальный шаблон для разных комбинаций whar_t и char
Здравствуйте, Videoman, Вы писали:
П>>Не понял, а в чем проблема расширять через промежуточный каст в unsigned char?
V>Он же обобщенный код хочет. А промежуточный каст wchar_t к unsigned char, это уже обрезание получается.
У него проблема с расширением char в wchar_t, наоборот — никаких проблем не должно быть.
А обобщенный код можно написать с использованием библиотечных "костылей" типа std::make_unsigned
Re[7]: Можно ли сделать универсальный шаблон для разных комб
Здравствуйте, Евгений Музыченко, Вы писали:
V>>Из описания замучаешься восстанавливать не работающий код.
ЕМ>В каком смысле "не работающий код"? Код здесь вообще ни при чем — проблема в том, что комбинация параметров шаблона (если в них явно добавлять промежуточный тип) не может быть однозначно выведена из комбинации параметров функции и ее возвращаемого типа. Получается, что решить можно только с костылями — хоть явными, хоть библиотечными. Придется их использовать.
Разумеется, нужный тебе промежуточный тип не может быть однозначно (и никак вообще) выведен, потому что правила выведения известны одному только тебе. А костыльным предложенное решение тебе видится только лишь потому, что ты не смог, или просто не удосужился, эти правила сформулировать.
Например, можно было бы сформулировать правило таким образом: "когда тип назначения (Dst) больше по рамеру, чем исходный тип (Src), выполнить промежуточное преобразование Src к беззнаковому типу, во всех остальных случаях промежуточный тип совпадает с Src". При такой формулировке, утилиту преобразования типов, предложенную здесь
Здравствуйте, rg45, Вы писали:
R>костыльным предложенное решение тебе видится только лишь потому, что ты не смог, или просто не удосужился, эти правила сформулировать.
Я уже много раз писал, что считаю "костыльными" любые решения, основанные на побочных эффектах использования шаблонов, хотя они давно стали нормой и освящены с самых высоких позиций. У меня нет проблем с формулировкой правил, а вот возможности довести их непосредственно до компилятора у меня нет — только путем влияния на его работу косвенно, через задницу. Но что ж делать — за неимением гербовой придется писать на клозетной.
Re[9]: Можно ли сделать универсальный шаблон для разных комб
ЕМ>Я уже много раз писал, что считаю "костыльными" любые решения, основанные на побочных эффектах использования шаблонов, хотя они давно стали нормой и освящены с самых высоких позиций.
И тебе не раз отвечали: считай что угодно, на здоровье.
ЕМ>У меня нет проблем с формулировкой правил,
Только, как минимум, уже двое человек не смогли понять, чего ты хочешь.
ЕМ>а вот возможности довести их непосредственно до компилятора у меня нет — только путем влияния на его работу косвенно, через задницу.
И опять все наоборот — у тебя есть возможность донести до компилятора многое, и тебе привели примеры, как это сделать.
ЕМ>Но что ж делать — за неимением гербовой придется писать на клозетной.
Я не пойму, зачем тебе этот плохой язык. Тебя принуждают его использовать?
--
Убегая от C++, ты убегаешь от себя (с) Shmj++
Re[10]: Можно ли сделать универсальный шаблон для разных комб
Здравствуйте, rg45, Вы писали:
R>как минимум, уже двое человек не смогли понять, чего ты хочешь.
Ну, кто-то мыслит в терминах задачи, как я, а кто-то — в терминах кода. Я тоже часто не понимаю, что хотят сказать те, кто вываливает кусок кода, добавляя к нему "не компилируется, в чем проблема?".
R>у тебя есть возможность донести до компилятора многое, и тебе привели примеры, как это сделать.
Еще раз: "довести до компилятора" — это объяснить нужные правила непосредственно ему. Когда для типа указывается модификатор unsigned или const, для числа — суффикс "длинное", для строки — префикс "широкая", то это оно самое. Когда используются побочные эффекты механизма, придуманного совсем для другого, просто потому, что "это работает" — это костыль. И очень удручает, что парадигма языка, предостерегая от чрезмерного использования побочных эффектов в "базовом" наборе функций, столь же чрезмерно поощряет это в шаблонном механизме, лишая язык более адекватных способов управления компиляцией.
R>Я не пойму, зачем тебе этот плохой язык. Тебя принуждают его использовать?
Покажите мне другой язык, на котором можно делать драйверы ядра для Windows, в котором накладные расходы не превышают микросекунд — я рассмотрю.
Re[11]: Можно ли сделать универсальный шаблон для разных ком
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Еще раз: "довести до компилятора" — это объяснить нужные правила непосредственно ему. Когда для типа указывается модификатор unsigned или const, для числа — суффикс "длинное", для строки — префикс "широкая", то это оно самое. Когда используются побочные эффекты механизма, придуманного совсем для другого, просто потому, что "это работает" — это костыль. И очень удручает, что парадигма языка, предостерегая от чрезмерного использования побочных эффектов в "базовом" наборе функций, столь же чрезмерно поощряет это в шаблонном механизме, лишая язык более адекватных способов управления компиляцией.
Я написал на "побочке", так как ты не соизволил сообщить какую версию компилятора С++ используешь. Из опыта общения предположил, что самую самую древнюю, которая еще как-то работает. В современном С++ для всего этого есть Concept-ы, где все уже пишется на адекватном, специально приспособленном для этого языке, всё как ты хочешь. В любом случае, так как ты работаешь с типами, это будет вызов мета-функции, хоть здесь, хоть там.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>У меня есть функции, реализации которых нужны для разных комбинаций 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]: Можно ли сделать универсальный шаблон для разных комб
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Я уже много раз писал, что считаю "костыльными" любые решения, основанные на побочных эффектах использования шаблонов, хотя они давно стали нормой и освящены с самых высоких позиций.
Причем тут SFINAE? Его, кстати, гораздо меньше в современных плюсах используют, потому что доработали язык. Но тебе не хочется изучать современный C++, гораздо проще скопом всё обозвать костылями
Здравствуйте, Videoman, Вы писали:
V>В современном С++ для всего этого есть Concept-ы, где все уже пишется на адекватном, специально приспособленном для этого языке
Согласен, забыл обозначить, что "самый современный" пока не подходит из соображений совместимости с прежними версиями винды.
Re[10]: Можно ли сделать универсальный шаблон для разных комб
Здравствуйте, Marty, Вы писали:
M>Причем тут SFINAE? Его, кстати, гораздо меньше в современных плюсах используют, потому что доработали язык.
Да, с опозданием лет на двадцать.
M>Но тебе не хочется изучать современный C++, гораздо проще скопом всё обозвать костылями
Изучать мне как раз хочется, но проблема в том, что в моей основной области (драйверы ядра под винду) в нагрузку к "современному C++" идет неадекватно тормозная студия вкупе с ограниченной совместимостью.