赞
踩
C++语言从1983年正式诞生以来,经历了多次的修订与改版,主要从包含两个大的节点,一是1998年,C++语言正式被C++标准委员会纳入标准,二是2011年,C++语言新增了许多新的特性,大大提升C++语言的实用性。可以把C++标准分成两个大的版本,C++1.0(C++98,C++03,C++03(tr1))和C++2.0(C++11,C++14,C++17,C++20(草案))
C++1.0和2.0的主要特性
C++版本 | 特性 |
---|---|
C++98 | 主要集成在兼容C特性的基础上增加面向对象的特性,包括类、简单继承、内联机制、函数默认参数以及强类型检查,虚函数、函数重载、引用机制(符号为&)、const关键字以及双斜线的单行注释,多重继承、保护成员以及静态成员等特性,并集成了标准模板库STL |
C++03 | 主要修订C++98中存在的问题 |
C++03(tr1) | 发布C++希望引入新特性的报告,但没有完全引入,后期加入部分std::tr1相关的功能 |
C++11 | 新增正则表达式(正则表达式详情)、完备的随机数生成函数库、新的时间相关函数,原子操作支持、标准线程库(2011之前,C和C++语言均缺少对线程的支持)、一种能够和某些语言中foreach语句达到相同效果的新的for语法、auto关键字、新的容器类、更好的union支持、数组初始化列表的支持以及变参模板的支持等等新特性 |
C++14 | 主要对C++11变准文案描述进行了修正 |
C++17 | 简化C++语言的日常使用 |
C++20 | – |
C++11核心功能 | MSVC | GCC | ICC | Clang | 替代方案 |
---|---|---|---|---|---|
Rvalue references | 10.0 | 4.3 | 12.0 | 2.9 | Boost.Move |
Rvalue references for *this | Nov 13 | 4.8.1 | 14.0 | 2.9 | |
Initialization of class objects by rvalues | 9.0 | 4.3 | 11.1 | 2.9 | |
Non-static data member initializers | 12.0 | 4.7 | 14.0 | 3.0 | |
Variadic templates | Nov 12 | 4.3 | 12.1 | 2.9 | |
Extending variadic template template parameters | Nov 12 | 4.4 | 12.1 | 2.9 | |
Initializer lists | Nov 12 | 4.4 | 14.0 | 3.1 | |
Static assertions | 10.0 | 4.3 | 11.1 | 2.9 | Boost.StaticAssert |
auto-typed variables | 10.0 | 4.4 | 12.0 | 2.9 | Boost.Typeof |
Multi-declarator auto | 10.0 | 4.4 | 12.0 | 2.9 | Boost.Typeof |
Removal of auto as a storage-class specifier | 10.0 | 4.4 | 12.0 | 2.9 | Boost.Typeof |
New function declarator syntax | 10.0 | 4.4 | 12.0 | 2.9 | Boost.ReturnType |
New wording for C++11 lambdas | 10.0 | 4.5 | 12.0 | 3.1 | Boost.Lambda |
Declared type of an expression | 10.0 | 4.3 | 12.0 | 2.9 | Boost.Typeof |
Incomplete return types | 11.0 | 4.8.1 | 12.1 | 3.1 | |
Right angle brackets | 9.0 | 4.3 | 11.1 | 2.9 | TR1 |
Default template arguments for function templates | Nov 12 | 4.3 | 12.1 | 2.9 | |
Solving the SFINAE problem for expressions | No | 4.4 | 12.1 | 2.9 | |
Template aliases | 12.0 | 4.7 | 12.1 | 3.0 | |
Extern templates | 9.0 | 4.3 | 11.1 | 2.9 | |
Null pointer constant | 10.0 | 4.6 | 12.1 | 3.0 | 自己实现的null_ptr |
Strongly-typed enums | 11.0 | 4.4 | 14.0 | 2.9 | #define |
Forward declarations for enums | 11.0 | 4.6 | 14.0 | 3.1 | |
Generalized attributes | 14.0 | 4.8 | 12.1 | 3.3 | |
Generalized constant expressions | Nov 13 | 4.6 | 14.0 | 3.1 | |
Alignment support | Nov 13 | 4.8 | No | 3.3 | |
Delegating constructors | Nov 12 | 4.7 | 14.0 | 3.0 | |
Inheriting constructors | Nov 13 | 4.8 | 15.0 | 3.3 | |
Explicit conversion operators | Nov 12 | 4.5 | 14.0 | 3.0 | |
New character types | 14.0 | 4.4 | 14.0 | 2.9 | |
Unicode string literals | 14.0 | 4.5 | 14.0 | 3.0 | |
Raw string literals | Nov 12 | 4.5 | 14.0 | 3.0 | |
Universal character name literals | 14.0 | 4.5 | 12.1 | 3.1 | |
User-defined literals | VS14 CTP1 | 4.7 | 15.0 | 3.1 | |
Standard Layout Types | 11.0 | 4.5 | No | 3.0 | |
Defaulted and deleted functions | 12.0 | 4.4 | 12.0 | 3.0 | |
Extended friend declarations | 10.0 | 4.7 | 12.0 | 2.9 | |
Extending sizeof | Nov 13 | 4.4 | 14.0 | 3.1 | |
Inline namespaces | 14.0 | 4.4 | 14.0 | 2.9 | |
Unrestricted unions | 14.0 | 4.6 | 14.0 | 3.1 | |
Local and unnamed types as template arguments | 9.0 | 4.5 | 12.0 | 2.9 | |
Range-based for | 11.0 | 4.6 | 13.0 | 3.0 | Boost.Foreach |
Explicit virtual overrides | 11.0 | 4.7 | 14.0 | 3.0 | #define |
Minimal support for garbage collection and reachability-based leak detection | 10.0 | No | No | No | |
Allowing move constructors to throw [noexcept] | Nov 13 | 4.6 | 14.0 | 3.0 | |
Defining move special member functions | 14.0 | 4.6 | 14.0 | 3.0 | |
Sequence points | 12.0 | 4.8 | 15.0 | 3.3 | |
Atomic operations | 11.0 | 4.4 | 13.0 | 3.1 | Boost.Atomic |
Strong Compare and Exchange | 11.0 | 4.8 | 13.0 | 3.1 | Boost.Atomic |
Bidirectional Fences | 11.0 | 4.8 | 13.0 | 3.1 | Boost.Atomic |
Memory model | 12.0 | 4.8 | No | 3.2 | Boost.Atomic |
Data-dependency ordering: atomics and memory model | 11.0 | 4.8 | No | 3.2 | Boost.Atomic |
Propagating exceptions | 10.0 | 4.4 | 12.0 | 2.9 | Boost.Exception |
Abandoning a process and at_quick_exit | 14.0 | 4.8 | No | No | |
Allow atomics use in signal handlers | 12.0 | 4.8 | No | 3.1 | |
Thread-local storage | 14.0 | 4.8 | No | 3.3 | Boost.Thread |
Dynamic initialization and destruction with concurrency | Nov 13 | 4.8 | No | 2.9 | |
func predefined identifier | Nov 13 | 4.3 | 11.1 | 2.9 | FUNCTION |
C99 preprocessor | No | 4.3 | 11.1 | 2.9 | |
long long | 9.0 | 4.3 | 11.1 | 2.9 | __int64 |
Extended integral types | No | No | No | No |
C++14核心功能 | MSVC | GCC | ICC | Clang | 替代方案 |
---|---|---|---|---|---|
Tweak to certain C++ contextual conversions | 12.0 | 4.9 | 16.0 | 3.4 | |
Binary literals | 14.0 | 4.9 | 11.0 | 2.9 | |
Return type deduction for normal functions | Nov 13 | 4.9 | 15.0 | 3.3 | |
Generalized lambda capture (init-capture) | 14.0 | 4.9 | 15.0 | 3.4 | |
Generic (polymorphic) lambda expressions | Nov 13 | 4.9 | 16.0 | 3.4 | |
Variable templates | 15.0 | 5.0 | No | 3.4 | |
Relaxing requirements on constexpr functions | 15.0 | 5.0 | No | 3.4 | |
Member initializers and aggregates | 15.0 | 5.0 | 16.0 | 3.3 | |
Clarifying memory allocation | No | No | No | 3.4 | |
Sized deallocation | 14.0 | 5.0 | 17.0 | 3.4 | |
[[deprecated]] attribute | 14.0 | 4.9 | 16.0 | 3.4 | |
Single-quotation-mark as a digit separator | 14.0 | 4.9 | 16.0 | 3.4 |
C++17核心功能 | MSVC | GCC | ICC | Clang | 替代方案 |
---|---|---|---|---|---|
static_assert with no message | 15.0 | 6 | No | 3.5 | C++11’s static_assert |
Disabling trigraph expansion by default | 12.0 | 5.1 | No | 3.5 | |
typename in a template template parameter | 14.0 | 5 | 17.0 | 3.5 | |
New auto rules for direct-list-initialization | 14.0 | 5 | 17.0 | 3.8 | |
Fold expressions | No | 6 | No | 3.6 | |
Attributes for namespaces and enumerators | 14.0 | 6 | No | 3.6 | |
u8 character literals | 14.0 | 6 | 17.0 | 3.6 | |
Nested namespace definition | 15.0 | 6 | 17.0 | 3.6 | |
Allow constant evaluation for all non-type template arguments | No | 6 | No | 3.6 | |
Remove deprecated register storage class | No | 7 | No | 3.8 | |
Remove deprecated bool increment | No | 7 | No | 3.8 | |
Make exception specifications part of the type system | No | 7 | No | No | |
__has_include in preprocessor conditionals | No | 5 | No | Yes | |
New specification for inheriting constructors (DR1941 et al) | No | 7 | No | 3.9 | |
[[fallthrough]] attribute | 15.0 | 7 | No | 3.9 | |
[[nodiscard]] attribute | No | 7 | No | 3.9 | |
[[maybe_unused]] attribute | No | 7 | No | 3.9 | |
Aggregate initialization of classes with base classes | No | 7 | No | 3.9 | |
constexpr lambda expressions | No | 7 | No | No | |
Unary Folds and Empty Parameter Packs | No | 6 | No | 3.9 | |
Differing begin and end types in range-based for | 15.0 | 6 | No | 3.9 | |
Lambda capture of *this | No | 7 | No | 3.9 | |
Direct-list-initialization of enums | No | 7 | No | 3.9 | |
Hexadecimal floating-point literals | No | 3.0 | No | Yes | |
Using attribute namespaces without repetition | No | 7 | No | 3.9 | |
Dynamic memory allocation for over-aligned data | No | 7 | No | No | |
Template argument deduction for class templates | No | 7 | No | No | |
Non-type template parameters with auto type | No | 7 | No | No | |
Guaranteed copy elision | No | 7 | No | No | |
Stricter expression evaluation order | No | 7 | No | No | |
Requirement to ignore unknown attributes | No | Yes | No | Yes | |
constexpr if-statements | No | 7 | No | 3.9 | |
Inline variables | No | 7 | No | 3.9 | |
Structured bindings | No | 7 | No | No | |
Separate variable and condition for if and switch | No | 7 | No | 3.9 | |
Matching template template parameters to compatible arguments | No | 7 | No | No | |
Removing deprecated dynamic exception specifications | No | 7 | No | No | |
Pack expansions in using-declarations | No | No | No | No |
example1 函数模板
//注意必须配一个无参的print函数,否则递归没有边界 void print() { } //定义一个模板函数 1 + n, 更具化, //(1)... 表示一个所谓的包(pack),一组 //(2)typename... Types 模板参数包 //(3)const Types&... args 函数参数类型包 //(4)args... 参数包 template <typename T, typename... Types> void print(const T& firstArg, const Types&... args) { std::cout<<"i'm 1+n"<<std::endl; std::cout<<firstArg<<std::endl; //递归() print(args...); } //n 更泛化,优先调用更具化的模板函数 template <typename... Types> void print(const Types&... args) { std::cout<<"i'm n"<<std::endl; //递归 print(args...); }
example2 类模板
//注意,一定要先加这一句 template <typename... Values> class MytestClassTem; template<> class MytestClassTem<>{}; template<typename First,typename... others> class MytestClassTem<First, others...> : private MytestClassTem<others...> { typedef MytestClassTem<others...> inherited; public: MytestClassTem(){} MytestClassTem(First v, others... args) :m_first(v), inherited(args...){} First first(){return m_first;} //此处返回的是父类的实例 inherited& other(){return *this;} protected: First m_first; }; /调用 MytestClassTem<int ,float,std::string> obj(41, 6.3, "hello"); std::cout<<"子级:"<<obj.first()<<std::endl; std::cout<<"子级的上一级:"<<obj.other().first()<<std::endl;
#include <vector>
typedef std::vector<std::vector<int> > Table; // OK
typedef std::vector<std::vector<bool>> Flags; // Error
#include <vector>
typedef std::vector<std::vector<int> > Table; // OK
typedef std::vector<std::vector<bool>> Flags; // OK
fun(0);//call fun(int)
int i = NULL;
fun(i);//call fun(int)
char* pp = NULL;
fun(pp);//call fun(void*)
fun(NULL);//有歧义
fun(nullptr);//call fun(void*)
//简单类型不建议使用auto
auto data = 2;
//typeid包含在#include <typeinfo>
std::cout<<typeid(data).name()<<std::endl;//i --- int
auto res = f();
std::cout<<typeid(res).name()<<std::endl;//f -- float
//auto 一般用于替代变量类型名字太长,或表达式类型太复杂的场景
std::vector<std::string> vecStr;
auto itr = vecStr.begin(); //auto取代 std::vector<std::string>::iterator itr = vecStr.begin()
auto lam = [](int x)->bool{return x = 0;}; // auto取代lambda表达式的类型
class TestInitializerList { public: TestInitializerList(int a, int b) { std::cout<<"TestInitializerList(int,int), a = "<<a<<",b="<<b<<std::endl; } TestInitializerList(std::initializer_list<int> initList) { std::cout<<"TestInitializerList(initializer_list<int> initList) ,vals = "; for(auto i : initList) { std::cout<<i<<","; } std::cout<<std::endl; } }; TestInitializerList a(77,5);//call TestInitializerList(int a, int b) TestInitializerList b{65,9};//若包含std::initializer_list<int>的构造函数存在,则调用,如不存在,则逐一分解,调用构造函数TestInitializerList(int a, int b) TestInitializerList c{34,56,78};若包含std::initializer_list<int>的构造函数存在,则调用,则分解,分解后若有匹配的构造函数则调用,没有匹配的会报错 TestInitializerList d={67,90};//同d{65,9};
before C++11
//小括号
Rect r(3,4);
r.printRect();
//大括号
int ia[2] = {3,4};
//赋值符号
Rect r1 = {4,5};//在C++11之前只能使用构造函数来对对象初始化
r1.printRect();
//C++11 Uniform Initializzation
int ib[2]{6,7};
std::vector<int> vec{8,9};
Rect r2{3,9};
r2.printRect();
//有了Initializer List后,直接不限个数,#include<algorithm>
std::cout<<std::max({1,2,3,4,5})<<std::endl;
//有了Initializer List后,直接不限个数,#include<algorithm>
std::cout<<std::min({1,2,3,4,5})<<std::endl;
int i;//i有一个未定义的值 std::cout<<i<<std::endl; int j{};//j被初始化为0 std::cout<<j<<std::endl; char* p;//p有一个未定义的指针值 std::cout<<p<<std::endl; char* q{};//q=nullptr std::cout<<q<<std::endl; int i(5.3);//将浮点型强制转换成整型 std::cout<<i<<std::endl; int j{5.0};//不会将浮点型强制转换成整型 std::cout<<j<<std::endl; char p{8};//OK std::cout<<p<<std::endl; char q{99999};//99999不在char范围内,无法强制转换 std::cout<<q<<std::endl;
struct TestExplicit { explicit TestExplicit(int re, int im = 0):real(re),imag(im) {} TestExplicit operator+(const TestExplicit& x) { return TestExplicit((real+x.real),(imag+x.imag)); } int real; int imag; }; TestExplicit a(12,5); std::cout<<a.real<<","<<a.imag<<std::endl; //编译器自动调用TestExplicit(int re, int im = 0)将int 5转换为TestExplicit对象 //若加上explicit ,则调用TestExplicit(int re, int im = 0)时需要更加明确,不能默认将int 转换为则调用TestExplicit TestExplicit b = a + 5; std::cout<<b.real<<","<<b.imag<<std::endl;
class TestNewExplicit { public: TestNewExplicit(int a,int b) { std::cout<<"TestNewExplicit(int a,int b), a = "<<a<<",b="<<b<<std::endl; } TestNewExplicit(std::initializer_list<int> initList) { std::cout<<"TestNewExplicit(std::initializer_list<int> initList) ,vals = "; for(auto i : initList) { std::cout<<i<<","; } std::cout<<std::endl; } explicit TestNewExplicit(int a,int b,int c) { std::cout<<"explicit TestNewExplicit(int a,int b,int c), a = "<<a<<",b="<<b<<",c="<<c<<std::endl; } }; TestNewExplicit p1(77,5); TestNewExplicit p2{77,5}; //TestNewExplicit p3{77,5,99,88}; //若不存在接收std::initializer_list<int>参数的构造函数,则需要编译器自动分解,匹配个数进行调用相应参数的构造函数 //若分解匹配后的构造函数前面加了explicit,则不能直接调用 //converting to 'TestNewExplicit' from initializer list to TestNewExplicit TestNewExplicit p4 = {1,2,3};
for(int i : {1,2,3,4})
{
std::cout<<i<<std::endl;
}
std::vector<int> vec{4,5,6};
for(auto& j : vec)
{
std::cout<<j<<std::endl;
std::cout<<"j的地址:"<<&j<<",vec[0]的地址"<<&vec[0]<<std::endl;
}
class Test { public: //不能使用编译器默认的构造函数 Test() = delete; Test(int a) { std::cout<<"Test(int a)"<<std::endl; } }; class Zoo { public: //自定义构造函数 Zoo(int i1,int i2):d1(i1),d2(i2) {} //拷贝构造函数,被删除 Zoo(const Zoo&) = delete; //移动构造函数 使用编译器默认的 Zoo(Zoo&&) = default; //赋值运算符 使用编译器默认的 Zoo& operator=(const Zoo&) = default; //移动赋值运算符 被删除 Zoo& operator=(const Zoo&&) = delete; virtual ~Zoo(){} }
名称 | 说明 |
---|---|
C++14标准PDF | https://doc.imzlp.me/viewer.html?file=docs/standard/isocpp2014.pdf |
C++11标准PDF | https://doc.imzlp.me/viewer.html?file=docs/standard/isoc11.pdf |
多种编译器对C++11的支持 | http://www.klayge.org/wiki/index.php/多种编译器对C%2B%2B11的支持 |
多种编译器对C++14的支持 | http://www.klayge.org/wiki/index.php/多种编译器对C%2B%2B14的支持 |
多种编译器对C++17的支持 | http://www.klayge.org/wiki/index.php/多种编译器对C%2B%2B17的支持 |
在线开发环境 | https://wandbox.org/ |
各VS版本对C++11功能的支持 | https://blog.csdn.net/xiaomu_347/article/details/82563688 |
侯捷老师的《C++11新特性》视频 | https://www.bilibili.com/video/av51863195/?p=9 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。