C++11/14/17新特性之 - if/switch 变量声明强化,结构化绑定,一致的初始化,自动推导,if constexpr,类型别名模板

本文介绍了C++的一些新特性,包括在if/switch中声明变量、结构化绑定的使用、一致的初始化方式、自动类型推导以及if constexpr的效率优化。通过实例展示了如何在实际编程中应用这些特性,提高代码的可读性和执行效率。同时,还提到了类型别名模板和默认模板参数。最后,提供了一个结构化绑定的实践案例。
摘要由CSDN通过智能技术生成

if/switch 变量声明强化

    void defineVarInIfOrSwithc() {
        // 在if,switch中直接定义变量
        vector<int> vec{1, 2, 3, 4, 5};
        if (auto iter = std::find(vec.cbegin(), vec.cend(), 4);iter != vec.cend()) {
            cout << *iter << endl;
        }
        if (auto iter = std::find(vec.begin(), vec.end(), 4);iter != vec.end()) {
            *iter *= 10;
        }
    }

结构化绑定

结构化绑定对写代码的便利性提升了很多

    std::tuple<string, int, double> foo() {
        return std::make_tuple("hello world", 2, 3.14);
    }

    void structuredBind() {
        // 结构化绑定
        vector<std::pair<string, int>> strIntVec{{"hello",      1},
                                                 {"world",      2},
                                                 {"hello",      3},
                                                 {"motherland", 4}};
        for (auto &[str, i] : strIntVec) {
            cout << str << ": " << i << endl;
        }

        auto[str, i, d] = foo();
        cout << str << ", " << i << ", " << d << endl;
    }

一致的初始化{}(C++11)

   // 一致的初始化
    class Foo {
    public:
        Foo() : a(0), b(0) {}

        Foo(int i, int j) : a(i), b(j) {}

        int a;
        int b;
    };

    void initializerList() {
        // {}一致的初始化,始自C++11
        Foo foo1(1, 2); // old c++
        Foo foo2{1, 2}; // 自定义类,
        Foo foo3{}; // 正确,用{}构造一个Foo对象,使用无参构造函数

        vector<int> vec{1, 2, 3, 4, 5}; // 容器
        std::unordered_map<string, int> strIntMap{{"lilei",     97},
                                                  {"hanmeimei", 99}}; // 容器
        int arr[]{1, 2, 3, 4, 5}; // 数组
        std::tuple<int, string, double> tuple3{1, "hello world", 3.14}; // std::tuple
        std::pair<int, string> p{1, "hello motherland"}; // std::pair
    }

自动推导

    // from C++11, 尾置返回类型
    template<typename T, typename U>
    auto add1(T t, U u) -> decltype(t + u) {
        return t + u;
    }

    // from C++14, auto自动推导
    template<typename T, typename U>
    auto add2(T t, U u) {
        return t + u;
    }

    void autoDeduc() {
        auto res1 = add1(1, 3.0);
        auto isDouble = std::is_same<decltype(res1), double>::value;
        auto res2 = add2(4.0f, 7.8);
        auto isFloat = std::is_same<decltype(res2), float>::value;

        return;
    }

if constexpr, 声明常量表达式的判断条件,提高效率

    // if constexpr, 声明常量表达式的判断条件,提高效率
    template<typename T>
    auto print_type_info(const T &t) {
        if constexpr (std::is_integral<T>::value) {
            return t + 1;
        } else {
            return t + 3.14;
        }
    }

    void ifConstexpr() {
        cout << print_type_info(1) << endl;
        cout << print_type_info(1.0) << endl;
        return;
    }

如上代码类似于如下代码

类型别名模板

   // 类型别名模板
    // 模板和类型的不同:模板是用来产生类型的,传统C++中,typedef 可以为类型定义一个别名,但是却没有办法为模板定义一个新的名称
    // 因为模板不是类型
    template<typename T, typename U>
    class MagicType {
    public:
        T t;
        U u;
    };

//    template<typename T>
//    typedef MagicType<std::vector<T>, std::string> FakeDarkMagic; // 错误, typedef不能是一个模板

    typedef MagicType<int, double> RightDarkMagic1; // 正确, 类型别名

    template<typename T>
    using RightDarkMagic2 = MagicType<std::vector<T>, std::string>; // 正确, 类型别名模板

    void typeAliaTemplate() {
        typedef int (*process)(void *); // 函数指针
        using newProcess = int (*)(void *); // 用新标准的using更直观了,支持范围更广
        RightDarkMagic2<int> magic;
        return;
    }

默认模板参数(好像没什么用???)

    // 默认模板参数 ,from c++11
    template<typename T = int, typename U = int>
    auto add3(T t, U u) {
        return t + u;
    }

    void defaultTemplateParam() {
        cout << add3(1, 2) << endl;
    }

练习:结构化绑定的应用

   // 结构化绑定练习
    template<typename Key, typename Value, typename F>
    void update(std::map<Key, Value> &m, F foo) {
        for (auto&&[key, value] : m) {
            value = foo(key);
        }
    }

    void struBind() {
        std::map<std::string, long long int> m{
                {"a", 1},
                {"b", 2},
                {"c", 3}
        };
        // 调用update更新value值
        update(m, [](std::string key) -> long long int {
//            return std::hash<std::string>{}(key);  // 注意,right,{}构造了一个std::hash<string>对象
            return std::hash<std::string>()(key);
        });

        // 输出结果
        for (auto&&[key, value] : m)
            std::cout << key << ":" << value << std::endl;
    }

 

参考:《现代C++教程:高速上手C++11 14 17 20》

https://github.com/changkun/modern-cpp-tutorial

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值