C++20 пользоватеский строковый литерал
От: B0FEE664  
Дата: 13.08.25 16:29
Оценка:
Меня наконец-то допустили до C++20 и вот...
думаю, что наконец-то смогу определять свои суффиксы ""_compile_time
Смотрю на нововведение здесь:
3) For user-defined string literals, let str be the literal without ud-suffix:
a) If the overload set includes a string literal operator template with a constant template parameter for which str is a well-formed template argument, then the user-defined literal expression is treated as a function call operator ""X<str>();

и несколько удивляюсь от там приведённого примера:

template<std::size_t N>
struct DoubleString
{
    char p[N + N - 1]{};
 
    constexpr DoubleString(char const(&pp)[N])
    {
        std::ranges::copy(pp, p);
        std::ranges::copy(pp, p + N - 1);
    }
};
 
template<DoubleString A>
constexpr auto operator""_x2()
{
    return A.p;
}

std::cout << "abc"_x2 << '\n';


Классно, думаю, загнули, но мне, надо попроще... и никак проще не получается.
Вопрос, короче, такой.
Допустим у нас есть функция:
template <auto>
constexpr auto fun()
{
    return 0;
}

И вызов
fun<"asdf">();

тогда — ошибка компиляции. Я ожидал, что для template <class T> auto fun(); T станет const char(&)[N] или что-то в этом роде.

Правильно ли я понимаю, что для строкового литерала никакого встроенного типа введено не было и всегда надо добавлять свой класс (вроде DoubleString из примера выше)?
И каждый день — без права на ошибку...
Re: C++20 пользоватеский строковый литерал
От: Кодт Россия  
Дата: 21.08.25 20:56
Оценка: 1 (1)
Здравствуйте, B0FEE664, Вы писали:

BFE>Меня наконец-то допустили до C++20 и вот...

BFE>думаю, что наконец-то смогу определять свои суффиксы ""_compile_time

.....

BFE>Правильно ли я понимаю, что для строкового литерала никакого встроенного типа введено не было и всегда надо добавлять свой класс (вроде DoubleString из примера выше)?


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

Я вот как раз щас говнокожу, хочу смешную статью на хабр написать.
Поэтому — пардоньте, что в дев-ветке, а не в майне. Under construction.
И вот как раз там нафигачил заготовку — компайлтаймовые строки.
https://github.com/nickolaym/nenormal/tree/dev/static_string/src

Ключевые особенности
— явный CTAD для того, чтобы параметр "размер" был без концевого нуля
— но концевой ноль в массив всё равно кладу, чтобы сишные строки получались
— для труЪ констекспра, зависящего от содержимого строки, приходится делать зависимые типы! хаскелл такое не умеет, а плюсы умеют!
Поэтому у меня два вида строковых литералов. Уот так уот.
Перекуём баги на фичи!
Re[2]: C++20 пользоватеский строковый литерал
От: B0FEE664  
Дата: 22.08.25 13:57
Оценка:
Здравствуйте, Кодт, Вы писали:

BFE>>Правильно ли я понимаю, что для строкового литерала никакого встроенного типа введено не было и всегда надо добавлять свой класс (вроде DoubleString из примера выше)?


К>Ссылка на голый массив буковок не является валидным параметром шаблона.

К>Поэтому и приходится изгаляться.

Я вроде бы разобрался, но всё равно остаюсь в легком недоумении.
Вот почему для нестроковых литералов можно объявить:
template<char... chRow>
consteval Num operator""_num()

а для строковых нельзя?

Причём, если я правильно понимаю, длина не ограничена:

auto x = 12345678901234567890123456789012345678901234567890_num;
auto y = 0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0_num;

test

Вот этого я не знал и сделал: ""_hex для строки
"123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0"_hex

что возвращает std::array конвертированных байтов.
Это не совсем правильно, потому что приходится руками проверять формат, а для 0xABC... это делается автоматически. Впрочем, всё равно consteval.

К>Я вот как раз щас говнокожу, хочу смешную статью на хабр написать.

К>Поэтому — пардоньте, что в дев-ветке, а не в майне. Under construction.
К>И вот как раз там нафигачил заготовку — компайлтаймовые строки.
К>https://github.com/nickolaym/nenormal/tree/dev/static_string/src
Они, всё же, constexpr, а не consteval...

К>- для труЪ констекспра, зависящего от содержимого строки, приходится делать зависимые типы! хаскелл такое не умеет, а плюсы умеют!

К>Поэтому у меня два вида строковых литералов. Уот так уот.
Два вида и суффикс должен быть согласован с содержимым строки?
Вот, опять же, для нестроковых литеров я могу:
template<char ch, char... chRow>
consteval char take0()
{
  return ch;
}

template<char... chRow>
consteval Num8 operator""_num8()  requires (sizeof...(chRow) < 5 && '2' != take0<chRow...>()) // 2 - исключительно для примера
{
    static_assert(
                   sizeof...(chRow) == 4  // 0xAB_num8
                   ||
                   sizeof...(chRow) == 3  // 0xA_num8 or 123_num8
                   ||
                   sizeof...(chRow) == 2  // 12_num8
                   ||
                   sizeof...(chRow) == 1  // 1_num8
                   , "invalid or unsupported format"
                 );
    return make_Num8<chRow...>();
}


а для строковых :
 constexpr cstring(const char(&s)[N+1]) requires (' ' != s[0])

error: ‘s’ is not a constant expression...

Я С++20 не знаю, только вот начал изучать на практике...
Так что может упускаю чего...
А! Вот! requires нужно в другом месте писать:
template<cstring V> constexpr requires(' ' != V.data_[0]) auto operator""_ss() { return V; }

Так или нет?


А ещё на ём можно Brainfuck написать.
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.