Меня наконец-то допустили до 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 из примера выше)?
Здравствуйте, B0FEE664, Вы писали:
BFE>Меня наконец-то допустили до C++20 и вот...
BFE>думаю, что наконец-то смогу определять свои суффиксы ""_compile_time
.....
BFE>Правильно ли я понимаю, что для строкового литерала никакого встроенного типа введено не было и всегда надо добавлять свой класс (вроде DoubleString из примера выше)?
Ссылка на
голый массив буковок не является валидным параметром шаблона.
Поэтому и приходится изгаляться.
Я вот как раз щас говнокожу, хочу смешную статью на хабр написать.
Поэтому — пардоньте, что в дев-ветке, а не в майне. Under construction.
И вот как раз там нафигачил заготовку — компайлтаймовые строки.
https://github.com/nickolaym/nenormal/tree/dev/static_string/src
Ключевые особенности
— явный CTAD для того, чтобы параметр "размер" был без концевого нуля
— но концевой ноль в массив всё равно кладу, чтобы сишные строки получались
— для труЪ констекспра, зависящего от содержимого строки, приходится делать зависимые типы! хаскелл такое не умеет, а плюсы умеют!
Поэтому у меня два вида строковых литералов. Уот так уот.
Здравствуйте, Кодт, Вы писали:
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 написать.