Modern C++ 的功能特性

刚刚毕业,开始了社畜生涯,谁能想到公司使用的还是VS2010(有限的C++11支持),预期会转移到VS2015(何年何月)。 本文记录一下那些常用的C++11后添加的功能特性。(每天写着写着老是被编译器暴打,希望以后能用上现代C++)

auto 关键字

C++11 ,VS2010 支持,,常用于遍历等情况

#include <iostream>
#include <vector>
int main()
{
    std::vector<int> vec;
    for(int i = 0; i < 100; ++i){
        vec.push_back(i);
    }
    auto iter = vec.begin();
    while (iter != vec.end()) {
        iter++;
        std::cout << *iter << std::endl;
    }
    return 0;
}

基于范围的 for 循环 (foreach)

C++ 11,VS2010支持,利用for上面的代码可以写成

#include <iostream>
#include <vector>
int main()
{
    std::vector<int> vec;
    for(int i = 0; i < 100; ++i){
        vec.push_back(i);
    }
    for(auto e: vec){
        std::cout << e << std::endl;
    }
    return 0;
}

nullptr

C++11,VS2010支持,比NULL更加现代,毕竟NULL == 0; 搞不好就认为是int了。 下面的代码只能在VS下编译,GCC会报错(error: call of overloaded 'Func(NULL)' is ambiguous)

#include <iostream>

void Func(int arg){
    std::cout << "int arg: " << arg << std::endl;
}

void Func(char* arg){
    std::cout << "char* arg:" << arg << std::endl;
}
int main()
{
    Func(NULL);
    return 0;
}

mutex

C++11,VS2010不支持,能用std的锁当然不要去自己实现或者用boost库 #include <mutex>

call_once / onec_flag

C++11,VS2010不支持,有了这个可以很好的实现线程安全的单例模式,当然局部静态变量(貌似也是C++11的)实现单例也很好。

static Singleton& GetInstance() {
    static std::once_flag s_flag;
    std::call_once(s_flag, [&]() {
      instance_.reset(new Singleton);
    });

    return *instance_;
}

https://blog.csdn.net/u011726005/article/details/82356538

chrono 时间库

C++11,VS2010不支持,谁能想到C++11以前只有time_t用,而time_t其实就是一个结构体! 当然VS2010还能用上MFC的COleDateTime也算曲线救国 #include <chrono>

decltype

C++11,VS2010不支持,大佬们用了都说好,我现在没用过,检查类型的东西

override

C++11,VS2010支持,貌似和Java的@Override一个东西,但是Java实质上只做一个标注,毕竟Java是有Interface的语言。 void foo() const override;

static_cast/reinterpret_cast/dynamic_cast/const_cast

C++0x,不是新东西,但是好用,少用点强制类型转换总是好的,不过貌似C++遇到(xxx*)C风格转换会自动使用以上的转换

https://zh.cppreference.com/w/cpp/language/explicit_cast

Lambda 表达式

C++11(泛型支持是C++14加进去的), VS2010支持,大佬们用了也都说好,不过个人没有常用,毕竟不像JS到处item.map(res => {xxx});,(rust 闭包真好用)。

auto sqar = [&](int x){return x*x;};
for(int i = 0; i < 10; ++i){
std::cout << sqar(i) << std::endl;
}

变长实参/形参包

C++11,VS2010 不支持,没有他之前va_start(),va_end(),有了它之后template<typename... Args>,看起来都清晰明了

template<typename ... Args>
std::string string_format( const std::string& format, Args ... args )
{
    size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
    if( size <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
    std::unique_ptr<char[]> buf( new char[ size ] ); 
    snprintf( buf.get(), size, format.c_str(), args ... );
    return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
}

https://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf


...

Some rights reserved
Except where otherwise noted, content on this page is licensed under a Creative Commons Attribution-ShareAlike 4.0 International license