Sirius' blog Sirius' blog
首页
  • 学习笔记

    • 《C++》
    • 《MATLAB》
    • 《Python》
  • 学习笔记

    • 《Git》
    • 《CMake》
  • 技术文档
  • 博客搭建
  • 学习
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Sirius0v0

怕什么真理无穷,进一寸有一寸的欢喜
首页
  • 学习笔记

    • 《C++》
    • 《MATLAB》
    • 《Python》
  • 学习笔记

    • 《Git》
    • 《CMake》
  • 技术文档
  • 博客搭建
  • 学习
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础

  • Cpp小记
  • C++学习笔记-220705-V1
  • 进阶

    • CC++模板
    • CC++STL-常用容器
    • CC++STL-函数对象
    • CC++STL-常用算法
    • 现代C++:常量、变量与类型推导
      • constexpr 关键字
      • C++17: if/switch 可以声明临时变量
      • auto 与 decltype 类型推导
        • 尾返回类型推导
        • 万能推导( decltype(auto) )
      • using: 创建类型别名
      • 结构化绑定
    • 现代C++:函数式编程(lambda、函数对象包装器)
    • 现代C++:右值引用、移动语义与完美转发
    • 现代C++:智能指针
    • C++11多线程编程
  • 奇思妙用

  • 库的使用

  • 《C++》学习笔记
  • 进阶
Sirius0v0
2023-08-15
目录

现代C++:常量、变量与类型推导

# 现代C++:常量、变量与类型推导

# constexpr 关键字

C++11 提供了 constexpr 显式的声明函数或对象构造函数在编译期会成为常量表达式。从 C++14 开始,constexpr 函数可以在内部使用局部变量、循环和分支等简单语句:

constexpr int fibonacci(const int n) {
    if(n == 1) return 1;
    if(n == 2) return 1;
    return fibonacci(n-1) + fibonacci(n-2);
}

# C++17: if/switch 可以声明临时变量

std::vector<int> v{1, 3, 5, 7};
if (auto it = std::find(v.begin(), v.end(), 3);
    it != v.end())
{
    std::cout << "Found it!\n";
}

# auto 与 decltype 类型推导

两个关键字均实现了类型推导,decltype 关键字是为了解决 auto 只能对变量进行类型推导的缺陷而出现的。decltype 还可以对表达式进行类型推导。

# 尾返回类型推导

template<typename T, typename Y>
auto test01(T x, Y y) -> decltype(x+y)
{
	return x + y;
}

auto res = test01<double, int>(3.14, 1);

# 万能推导( decltype(auto) )

如果有一个表达式,我不知道他是个可变引用( int & ),常引用( int const & ),右值引用( int && )还是一个普通的值( int ),这时候可以用:

decltype(auto) p = func();

一个例子:实现将两个不同类型vector逐元素相加的函数

template<typename T1, typename T2>
auto add(std::vector<T1> const &a, std::vector<T2> const &b)
{
    using T = decltype(T1{}+T2{});
    std::vector<T> ret;
    for (auto i = size_t(0); i < std::min(a.size(), b.size()); ++i )
    {
        ret.push_back(a[i]+b[i]);
    }
    return ret;
}

int main() {
    auto a = std::vector{1,2,3,4,5};
    auto b = std::vector{1.2,3.4,5.6};
    auto c = add(a, b);
    for (auto i = size_t(0); i < c.size(); ++i )
    {
        std::cout << c[i] << '\n';
    }
    return EXIT_SUCCESS;
}

# using: 创建类型别名

除了 typedef 外,可以用 using 创建类型别名:

typedef std::vector<int> VecInt;
using VecInt = std::vector<int>;

typedef int (*PFunc)(int);
using PFunc = int(*)(int);

# 结构化绑定

使用 std::tuple 可以囊括多个返回值,其中用 make_tuple 创建,在 C++17 之后完善了如何从元组中取元素

auto tup = std::make_tuple(3, 3.14f, "hello");
auto [name, age, height] = tup;
auto &[name, age, height] = tup;
auto &&[name, age, height] = tup;

结构化绑定不仅可以应用于 std::tuple,还可以应用于任意用户自定义类。

struct MyClass
{
    int x;
    float y;
};

MyClass mc = {42, 3.14f};
auto [x, y] = mc;
std::cout << x << ", " << y << '\n';
编辑 (opens new window)
#Cpp
上次更新: 2023/08/16, 16:01:49
CC++STL-常用算法
现代C++:函数式编程(lambda、函数对象包装器)

← CC++STL-常用算法 现代C++:函数式编程(lambda、函数对象包装器)→

最近更新
01
ipopt优化库配置及使用
07-21
02
ubuntu离线安装包的方法
07-21
03
其它控件的使用
03-05
更多文章>
Theme by Vdoing | Copyright © 2020-2024 Sirius0v0 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式