c++字面量

发展

自C++11以来添加了多线程模型,函数式编程功能等

字面量

基础数据类型都有字面量值,字面量值是固定的,也称为常量:

int unsigned_int = u'U'; // Unsigned integer
int hex = 0x2a; // Hexadecimal
std::string raw = R"(Raw String)"; // Raw string

lambda表达式是函数字面量:

[](int a, int b){ return a+b; }

Raw字符串

例如R"(Raw String)"写法,原始字符串,无视转义;对于路径表达式或者正则表达式很有用。注意:raw string可以跨越多行,其中的空白和换行符都属于字符串的一部分

raw字符串可以使用空串或者不超过16字符串(不含空格,反斜线)作为raw字符串的delimiter:

std::string raw = R"delimiter(Raw String)delimiter"

使用()和分隔字符串主要是为了使raw字符串可以更好包含

自定义字面量

C++11允许自定义字面量(解释含义/实际类型),通过给整型、浮点型、字符、C字符串加后缀和自定义操作符函数实现

  1. 语法
1010_b // Natural numbers 
123.45_km // Floating point numbers
"hello"_i18n // C-string literals
'1'_character // Character literals
<built_in-Literal>_<Suffix>
  1. 实现literal operator,运行时将用户定义的字面量映射到对应的函数结果
int operator"" _b(unsigned long long bin) //C++14中函数中_b前没有空格
{
	return 3;
}

作用:用户定义字面量到运算符的自动映射,可以实现类型安全算术,如编译器确保不可能将苹果和梨想加。

注意:如果是-100_b运算符的参数只会使用解析的100,返回的数字再和-运算为负数

C++14内置的字面量

C++14包含一些二进制数字、C++字符串、复数、时间单位的字面量,内置语法中只有前缀或后缀不加_

  • 过去C++ 只支持 C 字符串字面量,必须始终使用 C 字符串(char [])来初始化 C++ 字符串;C++14 中,第一次支持字符串类型字面量
  • 使用字符串字面量,需要using namespace std::literals;
  • 时间字面量属于类型 std::chrono::duration,需要using namespace std::literals::chrono_literals;
  • 时间字面量支持基本的加法、减法、乘法、除法和模运算

2种自定义字面运算符

  • raw运算符 接收参数 (const char*, size_t), (const char*) or const char
  • cooked运算符 接收参数 (long double), (unsigned long long int)

只有raw literal operators形式的运算符才可以处理C语言形式字面字符串和字符,总结:

  • 除了char数据类型,C ++支持的数据类型wchar_tchar16_tchar32_t,可以使用这些类型作为C字符串的底层类型(图中举例char
  • 对数整型或浮点数,如果同时实现两个版本,编译器将选择Cooked形式,它具有更高的优先级
  • 如果使用long double运算符,整型字面量则不能调用,需要进行重载才可以

函数签名总结

例子

举例说明内置时间字面量的用法,例如s(seconds),m(minute),h(hours)等都是std:chrono::duration类型对象:

/// milliseconds
 using milliseconds	= duration<_GLIBCXX_CHRONO_INT64_T, milli>;
/// seconds
using seconds	= duration<_GLIBCXX_CHRONO_INT64_T>;
/// minutes
using minutes	= duration<_GLIBCXX_CHRONO_INT64_T, ratio< 60>>;
/// hours
using hours	= duration<_GLIBCXX_CHRONO_INT64_T, ratio<3600>>;

#if __cplusplus > 201703L
/// days
using days = duration<_GLIBCXX_CHRONO_INT64_T, ratio<86400>>;
...
#endif // C++20

#include <chrono>
#include <iostream>

using namespace std::literals::chrono_literals;

int main() {
    std::cout << std::endl;

    typedef std::chrono::duration<long long, std::ratio<2700>> hour;
    auto schoolHour = hour(1);
    // auto schoolHour= 45min;

    auto shortBreak = 300s;
    auto longBreak = 0.25h;

    auto schoolWay = 15min;
    auto homework = 2h;

    auto schoolDayInSeconds = 2 * schoolWay + 6 * schoolHour + 4 * shortBreak + longBreak + homework;

    std::cout << "School day in seconds: " << schoolDayInSeconds.count() << std::endl;

    std::chrono::duration<double, std::ratio<3600>> schoolDayInHours = schoolDayInSeconds;
    std::chrono::duration<double, std::ratio<60>> schoolDayInMinutes = schoolDayInSeconds;
    std::chrono::duration<double, std::ratio<1, 1000>> schoolDayInMilliseconds = schoolDayInSeconds;

    std::cout << "School day in hours: " << schoolDayInHours.count() << std::endl;
    std::cout << "School day in minutes: " << schoolDayInMinutes.count() << std::endl;
    std::cout << "School day in milliseconds: " << schoolDayInMilliseconds.count() << std::endl;

    std::cout << std::endl;
}


posted @ 2021-11-06 00:02  qxxiao  阅读(899)  评论(0)    收藏  举报