Пользовательские литералы для строки по сравнению с шестнадцатеричным значением - PullRequest
3 голосов
/ 02 августа 2020

Что касается этого вопроса , почему aa определяемый пользователем литерал для шестнадцатеричного значения отображается на другой оператор строкового литерала, чем строка? То есть, почему код

std::vector<uint8_t> val1 = 0x229597354972973aabbe7_hexvec;

сопоставляется с

std::vector<uint8_t> operator"" _hexvec(const char*str)
{
    // Handles the form 0xFFaaBB_hexvec and 0Xf_hexvec
    size_t len = strlen(str);
    return convertHexToVec(str, len);   
}

, а код

std::vector<uint8_t> val2 = "229597354972973aabbe7"_hexvec;

сопоставляется с

std::vector<uint8_t> operator"" _hexvec(const char*str, std::size_t len)
{
    // Handles the conversion form "0xFFAABB"_hexvec or "12441AA"_hexvec
    return convertHexToVec(str, len);
}

Что делает size_t необходимым, когда оба являются нулевыми терминальными строками? В этом отношении, почему 0x551A_hexve c вообще строка? Почему не целое число?

1 Ответ

5 голосов
/ 02 августа 2020

Что делает size_t необходимым, когда обе являются нулевыми терминальными строками?

В C ++ нет правила, согласно которому строковый литерал не может иметь встроенных в него символов NUL. "Nul\0character" - допустимый строковый литерал C ++. А при обработке UDL язык C ++ хочет убедиться, что вы знаете, какие байты на самом деле являются частью строки. Для этого вам понадобится размер.

Кроме того, он позволяет системе различать литералы, предназначенные для работы со строками, и литералы, предназначенные для работы с числами. Литерал 21s может означать 21 секунду, а литерал "21"s может означать std::string, содержащий строку символов «21». И оба литерала могут быть в области видимости без каких-либо перекрестных разговоров.

Numeri c буквальные UDL-функции не используют size_t, чтобы отличить себя от перегрузки, предназначенной для строковых литералов. Однако numeri c literal не может содержать в себе символ NUL, поэтому они не сильно теряют, если им не задан размер.

В этом отношении, почему 0x551A_hexve c это вообще строка? Почему не целое число?

Потому что это то, что вы просили .

Ваша функция UDL для числовых c литералов может обрабатывать необработанные литеральные данные (как строка) или синтезированное буквальное значение. Если вы используете const char* версию UDL, вы запрашиваете обработку необработанных литеральных данных.

Синтезированное буквальное значение - это тип C ++, вычисляемый из литерала с использованием обычных правил для литералов. Для целочисленных числовых c литералов синтезируемое буквальное значение имеет unsigned long long: самый большой фундаментальный целочисленный тип, доступный для C ++:

std::vector<uint8_t> operator"" _hexvec(unsigned long long value);

Конечно, тот факт, что unsigned long long имеет Конечный размер - именно поэтому существует необработанная буквальная версия. Литерал 0x229597354972973aabbe7 не может поместиться в unsigned long long, но вы все равно можете захотеть уместить его в создаваемый вами объект. Следовательно, у вас должен быть доступ к фактическим символам буквального значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...