前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 11 新特性

C++ 11 新特性

作者头像
HauHau
发布2022-01-12 09:14:23
2960
发布2022-01-12 09:14:23
举报
文章被收录于专栏:叹世界叹世界

C++ 11 的一些新特性

原始字面量

R("string...")

示例:

代码语言:javascript
复制
#include <iostream>

int main() {
    std::string str = R"(../../text.cc
    
    上面换了个行)";
    std::cout << str << std::endl;
}

[Running] cd "/root/code-server/c11-new/" && g++ 字符串字面量.cc -o 字符串字面量 && "/root/code-server/c11-new/"字符串字面量
../../text.cc
    
    上面换了个行

[Done] exited with code=0 in 0.269 seconds

nullptr

这个没什么好说的,替换 NULL 使用即可,这玩意不等于 0

auto & decltype 自动推导

auto 只能推导初始化了的变量

decltype 根据表达式进行推导: decltype (表达式)

decltype 的特殊情况:

  • 如果表达式为函数调用,则推导的类型和函数返回值相同
  • 如果表达式为左值或者被 () 包围,推导出来的是表达式类型的引用

骚操作:

  • 返回类型后置
代码语言:javascript
复制
/**
 * @brief 阻塞等待 set_value
 * @return ret_type
 */
auto get_return() -> decltype(p_.get_future().get()) {
  return p_.get_future().get();
}
  • 使用 decltype 的推导规则进行类型推导,auto 有些时候会推导错误
代码语言:javascript
复制
/**
 * @brief 阻塞等待 set_value
 * @return ret_type
 */
decltype(auto) get_return() {
  return p_.get_future().get();
}

final & override

没啥好说的

函数模板默认参数

如题:

代码语言:javascript
复制
template<typename ret_type=int>
decltype(auto) get_return(ret_type _ret) {
  return _ret
}

要注意的是,函数模板默认参数没有函数默认参数的默认参数都必须在右边的限制,想放哪就放哪

委托构造函数

允许构造函数调用其他构造函数,建议在初始化列表中使用

代码语言:javascript
复制
public:
  explicit TestTask(std::string _name) : name_(std::move(_name)) {};
  TestTask(std::string _name, const std::string& _text) : TestTask(std::move(_name)) {
    std::cout << _text << std::endl;
  }

继承构造函数

派生类可以直接使用基类的构造函数: using qualifier::name;

代码语言:javascript
复制
class TestTask : public XTask<std::string> {
	public:
  	std::string name_;

  public:
  	TestTask() = default;
  	explicit TestTask(std::string _name) : name_(std::move(_name)){};
}

class Task : public TestTask {
	public:
		using TestTask::TestTask;
};

也可以通过这种方式来使用基类的隐藏的同名函数

std::initializer_list

一个轻量的类模板,通过这个模板可以实现任意长度参数的传递

传参的时候可以通过实例化 std::initializer_list 或者使用初始化列表 { } 来进行传参

代码语言:javascript
复制
#include <iostream>

template<typename T>
void set_return(std::initializer_list<T> _list) {
  for (const auto &i : _list){
    std::cout << i;
  }
  std::cout << std::endl;
}

int main() {
  std::initializer_list<int> list{1, 2, 3, 4, 5};
  set_return(list);
  set_return({1, 2, 3, 4, 5});

  return 0;
}

同时也可以在构造函数中使用 std::initializer_list 来传递多个实参

for

代码语言:javascript
复制
for (const auto &i : _list){
  std::cout << i;
}

其实就是使用迭代器来遍历容器

代码语言:javascript
复制
for (auto it = _list.begin(); it != _list.end(); ++it){
  std::cout << i;
}

包装器和绑定器

右值引用

  • 左值:放在内存、有明确存储地址(可以取地址)的数据
  • 右值:可以提供数据值的数据(不可以取地址)

人话:能对表达式取地址的是左值,否则为右值,即:有名字的变量或对象都是左值,右值都是匿名的

右值又分两种:

  • 将亡值 (xvalue, expiring value): 非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和 lambda 表达式等
  • 纯右值 (prvalue, PureRvalue): 与右值引用相关的表达式,比如,T&& 类型函数的返回值、 std::move 的返回值等

右值引用:

代码语言:javascript
复制
class Test {
  Test() = default;
}

Test GetTest() {
    return Test();
}

int main() {
  int &&value = 666;
  Test &t = GetTest();
  Test &&t = GetTest();
  const Test &t = GetTest();
  return 0;
}

666 是纯右值,int &&value = 666; 没毛病

Test &t = GetTest(); 将一个右值赋值给左值引用,出大问题;Test &&t = GetTest(); 就没毛病

const Test &t = GetTest(); 有点特殊:常量左值引用是一个万能引用类型,可以接受左值、右值、常量左值、常量右值

为什么使用右值引用?

充分利用临时变量,减少不必要的拷贝

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原始字面量
  • nullptr
  • auto & decltype 自动推导
  • final & override
  • 函数模板默认参数
  • 委托构造函数
  • 继承构造函数
  • std::initializer_list
  • for
  • 包装器和绑定器
  • 右值引用
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档