半小时入门 C++ 17

1. SFINAE In C++ 17

模版变量

C++ 14 之后,编译器开始支持变量的模版化,该技术可用不同类型存储同一常数,或成为访问模板类成员的语法糖。

constexpr增强

constexpr 可以用于 if 语句,再结合元编程,可以在编译阶段实现对不同类型数据的访问控制,将同一个算法应用于不同的数据结构,即使他们存在细微的差异。从而大幅度提高接口的复用率。

template<classs T>
void getFuncName(T expr) {
	// Same logic
	...
	if constexpr (std::is_same_v<T, std::string>) {
		return expr;
	}
	else if constexpr (std::is_arithmetic_v<T>) { 第二个判断语句
		return itos(expr.name());
	}
	else { 第三个判断语句
        expr.name()
	}
	// Same logic
	...
}

该方法常用于模板类中的函数或模版函数。
C++ 元编程参考手册

常用的元编程模版

enable_if
is_pointer
is_arithmetic
is_reference
is_same
is_base_of
remove_const
remove_pointer
remove_reference

除此之外 is_detected 也是一个非常有用的模版。
在实际使用中,开发者通常会基于元编程库定义自己的元模版以提高代码可读性。

类模板实参推导

template<class T>
class A
{
    A(T, T);
};
auto y = new A(1, 2);   // 分配的类型是 A<int>

// 不用再写成
// A<int> y = new A(1, 2); // 分配的类型是 A<int>

C++ 20 之后concept和constraint方案,极大的简化了SFINAE的条件限制语法,建议大家可以自己去看一看。

2 其他特性

if 和 case 初始化器

可用于缩小临时变量的作用域。

    if (int i = 10; i > 0)  {
        std::cout << "Value:  " << i << std::endl;
    } else {
        std::cout << "To small" << std::endl;
    }

auto 可以用于lambda函数中,同时auto也可以用于函数返回值处

auto glambda = [](auto a, auto&& b) { return a < b; };

auto f() { return x; }        // 返回类型是 int
const auto& f() { return x; } // 返回类型是 const int&

decltype(auto) f() { return x; }   // 返回类型是 int,同 decltype(x)
decltype(auto) f() { return (x); } // 返回类型是 int&,同 decltype((x))

如果函数返回类型没有使用 decltype(auto),那么推导遵循模板实参推导的规则进行。

支持二进制字面量,支持数字分隔符

int b = 0b101010; // C++14
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14

强制的复制消除

函数返回时,不会多次构造临时变量。

命名空间简写

namespace Q
{
    namespace V  {
    ... // V 是 Q 的成员,且完全在 Q 内定义
   	}
}

// C++17 起可以用来替代以上几行
namespace Q::V {
	...
}

折叠表达式

语法糖,用于计算模版行参包

结构化绑定声明

int a[2] = {1, 2};
 
auto [x, y] = a;    // 创建 e[2],复制 a 到 e,然后 x 指代 e[0],y 指代 e[1]
auto& [xr, yr] = a; // xr 指代 a[0],yr 指代 a[1]
// 数组,结构体,等等

对于元组的操作也可以使用std::tie 和 std::get

属性

用于标识函数、语句、变量的一些特点。
如:
[[maybe_unused]] 用于标识函数内可能没有用到的变量。
[[nodiscard]] 用于标识函数返回值不可以被忽略

更多的属性可以参考:C++ Attribute

属性这个功能应该是参考GCC编译器的 attribute 功能,有兴趣的可以参看 GCC 文档 的对应章节。比如 attribute (packed) 。

工具类和方法

std::any
std::optional
std::string_view
std::apply
std::variant
std::make_from_tuple

std::pmr 机制

一种内存分配机制,用于减少new、delete的开销,减少碎片化的内存,从而提高效率。其中预定义大量的模版容器。通过预定义内存并利用这些容器来实现算法,从而提高效率。

如果你的项目中存在频繁的new、delete小型类的情况,建议考虑使用std::pmr。

一个非常简单的示例:

#include <memory_resource> 
#include <string> 
#include <iostream> 
int main()
{
   std::pmr::monotonic_buffer_resource pool;
   std::pmr::vector<std::pmr::string> container{&pool} ;
   for(int i=0;i<100;i++)
   {
       container.push_back("this is a test for use pmr and you know the length id over 15");
   }
   
    for(int i=0;i<100;i++)
   {
       std::cout << container[i] << std::endl;
   }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值