170 похожих чатов

Народ, возможно ли в С++ написать constexpr-функцию которая парсит число

из строки и выдает разный тип в зависимости от значения (или int или double) ?
static_assert(parseNumber("123") == 123);
static_assert(parseNumber("123.123") == 123.123);
Или так в С++ сделать невозможно и мы вынуждены передавать строку через шаблонный параметр?
static_assert(parseNumber<"123">() == 123);
static_assert(parseNumber<"123.123">() == 123.123);

40 ответов

26 просмотров

нет нельзя, лучшее что можно это вариант

предположим, что возможно. какая у неё сигнатура?

Первое опять про constexpr-параметры (которых нет).

feedable
ну дефолтное auto(auto)

это не сигнатура. в сигнатуре конкретные типы

feedable
да нет они тут не нужны

Хочется в constexpr-контекст внутри (или в trailing-type) затащить значение параметра. Как не нужны?)

Sergey Anisimov
Хочется в constexpr-контекст внутри (или в trailin...

тут можно было бы сделать так чтоб принимаемый параметр был рантаймовым

Богдан- Автор вопроса
feedable
через рассахаривание-варианта

А, это опять про то предложение...

feedable
через рассахаривание-варианта

Давай обсуждать C++, а не выдуманный язык

Богдан- Автор вопроса
Sergey Anisimov
Первое опять про constexpr-параметры (которых нет)...

кажется я понял, ну что ж, будем ждать constexpr-параметры в С++26 стандарте

Богдан
кажется я понял, ну что ж, будем ждать constexpr-п...

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

Богдан- Автор вопроса

А пока я пытаюсь реализовать вариант с передачей строки через шаблонный параметр и не могу понять как в if-constexpr/if-consteval задетектить ошибку компиляции (или компайл-тайм интерпретации) которая выбрасывается consteval-функцией через throw чтобы при интанциировании была отброшена ненужная ветка и auto не ругался на то что мы возвращаем разные типы Вариант 1 (через if-consteval) template <string_literal str> constexpr auto parseNumber() { if consteval { return stoi(str.value); } else { return stod(str.value); } } int main(){ static_assert(parseNumber<"123">() == 123); static_assert(parseNumber<"123.123">() == 123); } не работает и ругается на несовпадение типов возврата: error: inconsistent deduction for auto return type: 'int' and then 'double' Вариант 2 (через if-constexpr + requires{..}) template <string_literal str> consteval auto parseNumber() { if constexpr(requires { stoi(str.value); }) { return stoi(str.value); } else { return stod(str.value); } } int main(){ static_assert(parseNumber<"123">() == 123); static_assert(parseNumber<"123.123">() == 123); } не работает и ругается на error: expression '<throw-expression>' is not a constant expression Вот полная демка - https://godbolt.org/z/jGqcfhvKs Кто-нибудь может объяснить это поведение и как это можно решить?

Возможно

Богдан
кажется я понял, ну что ж, будем ждать constexpr-п...

вообще если тебе пофиг на рантайм то можешь юзать хана::тайп_ц

Богдан- Автор вопроса
Андрей Будиловский
Не будем, вроде же комитет сказал, что компиляторы...

В чем тут сложность реализации? Разве constexpr-параметры это не синтаксический сахар? Компилятору достаточно посмотреть что параметр объявлен как constexpr и будет трактовать его как шаблонный параметр. То есть вот такой код auto someFunc(constexpr string_literal str, auto someParam){ ... } Будет эквивалентен такому коду template<string_literal str> auto someFunc(auto someParam){ ... }

Богдан
В чем тут сложность реализации? Разве constexpr-па...

там гвоздями всё прибито, что это не так

Богдан
В чем тут сложность реализации? Разве constexpr-па...

предыдущие пропозалы делали так что констекспр это и кт и рт может быть

Делается тривиально кстати

d7d1cd
Нуу. Покажите как

ну второе реально делается, тривиальная реализация: в constexpr ищем . и это делаем в отдельной consteval функции

Богдан
А пока я пытаюсь реализовать вариант с передачей с...

std::from_chars не бросает исключение. Жаль тоже не constexpr

Alexander Karaev
constexpr частично, только для целых

Оу, а я думаю где надпись-то. А она в зелёной скобке. Обычно constexpr версия выписана отдельно

Alexander Karaev
constexpr частично, только для целых

И это очень хорошо. Потому что все преобразования для floating в любых направлениях дикий матан.

Jokhar Ali
https://godbolt.org/z/Whs6KG1hj

Стринг литерал, кстати, необязательно создавать отдельно

Андрей Будиловский
Стринг литерал, кстати, необязательно создавать от...

Так оно для наглядности ты можешь сразу ее подсунуть

Богдан- Автор вопроса

Спасибо за пример. Но по-прежнему остается вопрос почему if consteval {} не умеет отбрасывать ветку (которая не может выполниться в компайл-тайме) при интанциировании функции. То есть я пытаюсь запарсить число из строки в компайл-тайме int stoi(const char*); double stod(const char*); template <string_literal str> constexpr auto parseNumber() { if consteval { return stoi(str.value); } else { return stod(str.value); } } и процессе компайлт-тайм интерпретации вызывается функция stoi которая выбрасывает исключение через throw. Но throw это невалидная конструкция для constexpr-функции и по идее компилятор должен обросить первую ветку и перейти к else-ветке при инстанциирования но этого не происходит и компилятор ругается на неконсистетность типа возрата Но еще больше меня беспокоит почему конструкция if constexpr(requires { stoi(str.value); }){ return stoi(str.value); } else { return stoi(str.value); } не может поймать ошибку, ведь это сильно похоже на обращение к несуществующим полям на объекте struct X { int field; } struct Y { int someField; } auto func(auto obj){ if constexpr(requires{ obj.someField }) { obj.someField; } else { obj.field; } } int main(){ func(X{}); func(Y{}); } Или ответ заключается в том что конструкция if constexpr(requires{ ... }){ ... } может ловить лишь sfinae-out ошибки компиляции а throw при компайл-тайм выполнении constexpr функции это уже "hard error" ??

Второе

Богдан- Автор вопроса
Jokhar Ali
Второе

Интересно, а есть ли где-то обсуждения почему так решили? Или может не захотели усложнять? Интересно есть ли уже пропозал к С++26 про то чтобы перевести throw-ошибки (для constexpr-функций) в разряд sfinae-out ошибок?

Богдан
Спасибо за пример. Но по-прежнему остается вопрос ...

if consteval {} выбирает ветку if, если вычисление функции происходит в ct, иначе ветку else От внутренностей веток if consteval {} не зависит. Она уже выполняется либо так, либо эдак

Похожие вопросы

Обсуждают сегодня

а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
63
Всем привет! Подскажите. Я написал приложение на Delphi 10.2 Tokyo под Windows 10. И передо мной стал вопрос о том чтобы сделать это приложение кроссплатформенным (под Linux и...
Дмитрий Завгородний
24
Почему стало ломаться на D11? "739002.86400000' is not a valid timestamp" function IncDateTime(aStamp:TTimeStamp;aKind:TTriggerKind;aInterval:Integer):TDateTime; //aStamp = 2...
Катерина Свиридова
8
Привет всем. Подскажите где можно посмотреть, какая версия электрон, поддерживает версии windows? Некий changelog. Мне бы желательно, поддержку 7,8,10... latest, как понимаю и...
Anonym Squad
21
Портфолио: Зовут меня Александр, мне 36 лет. Город Пушкино. Общий рабочий стаж: ~14 лет Уровень квалификации: Senior Full-stack developer Где прочесть мой код? https://github....
Magic
10
Есть ли смысл устраиваться на 1с ? Даст это плюс в дальнейшем трудоустройстве на php? Просто у меня в городе вакансий на пхп нету. Или лучше удаленно искать. Опыта работы нету...
Azamat
14
Не ну фпц - это уже просто троллинг какой-то. Элементарный код нельзя собрать. ЧЯДНТ? program Project1; {$mode delphi} uses SysUtils, Classes, Generics.Collections; var...
Peter
4
а где есть mysql cloud кроме яндекс-клауд?
Oleg Nosov
13
hi im a cs student. i need some advice from people who have enough experience in Embedded Software. I need to know whether this profession is suitable for me. I have watched s...
Sahand 🏔️
8
А кто-нибудь запихивал сборку перловых модулей/образов с perl приложениями в окружения без интернета (в специализированном CI/CD)? У меня сейчас есть ряд cpanfile, которые н...
Andrey Smirnov / 𝓪𝓵𝓵𝓽𝓮𝓻 /
14
Карта сайта