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 ответов

84 просмотра

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

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

Первое опять про 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-па...

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

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

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 {} не зависит. Она уже выполняется либо так, либо эдак

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта