C++11/14/17 新特性总结

C++11/14/17 新特性总结

  • initializer_list
	std::vector<int> vctInts({92, 12, 39, 46, 92, 84, -1, 0, -234});
  • auto
	std::vector<int> vctInts({92, 12, 39, 46, 92, 84, -1, 0, -234});
	for (const auto& item : vctInts)
	{
		std::cout << item << std::endl;
	}

  • decltype

用于模板函数的参数返回类型声明

template <typename T, typename U>
auto MyFunc(T t, U u) -> decltype(t + u)
{
	return t + u;
}

用于对lambda函数类型自动推导

	auto func = [](int a, double b, const std::string& strTmp)->std::string {
		boost::format fmt("%1%  %2%  %3%");
		fmt % a% b% strTmp;
		return fmt.str();
	};

	/*
	auto func2 = [](int a, double b, const std::string& strTmp)->std::string {
		char buf[1024] = { 0 };
		memset(buf, 0, sizeof(buf));
		sprintf_s(buf, "%d %.8f %s", a, b, strTmp.c_str());
		return std::string(buf);
	};
	*/

	std::map<int, decltype(func)> fucMap;

	fucMap.insert( std::make_pair(0,   func) );
	//fucMap.insert( std::make_pair(1, );

	auto it = fucMap.find(0);
	BOOST_CHECK_EQUAL( fucMap.end()== it, false);
	std::cout << it->second(10, 1.23, std::string("hello")) << std::endl;

  • override 和 final

override 用于来声明重写父类虚函数
final 用来修饰一个类是,表明一个类禁止被继承; 用来修饰虚函数时, 表明虚函数不能被重写

  • 函数返回类型后置 (用于模板函数)

  • 模板别名: using


typedef std::vector<std::map<std::string, std::string>>::iterator  itMaps;
using itMaps = std::vector<std::map<std::string, std::string>>::iterator  ;

using可以用于模板的别名定义, typedef 则不可以

template<typename T>
using it12Items = std::array<T, 12>;   

  • nullptr
    用来取代 NULL

0 == nullptr;  //true
NULL == nullptr;  //true


  • 智能指针
shared_ptr
unique_ptr
weak_ptr
  • 异常规范

foo()noexcept
foo()noexcept(false)
foo()noexcept(true)


  • explicit

C++11之前仅限制单个参数的构造函数做隐式转换
C+++11开始不限于单个参数的构造函数

  • 可变参数模板
    一般用递归的方式逐步减少参数的个数 , 递归终止于0个参数

//递归结束
void XPrint()
{
}


template< typename T, typename ...Types>
void XPrint(const T& first,  const Types&... otherArgs)
{
	PlainPrint(first);
	XPrint( otherArgs... );
}



BOOST_AUTO_TEST_CASE(test_variadic_templates)
{
	std::cout << "hello  ............" << std::endl;

	XPrint(2, 5.231, std::string("hello"), "niuniu", std::complex(5, 1));

}

  • 右值引用和移动语义

注意自己实现移动拷贝(move ctor)的时候(有指针), 收尾时需要将被move的对象的指针设置为NULL


std::vector<std::string> vctInts;
vctInts.push_back(std::move( std::string("hello") ));

  • 原生字符串支持

    //std::string  strFilePath1 = "C:\\Program Files (x86)\\Tencent\\QQ\\gf-config.xml"; //ok
    
    //std::string  strFilePath1 = R"(D:\gradle-6.0-bin.zip)"; //ok
    
    std::string  strFilePath1 = R"(C:\Program Files (x86)\Tencent\QQ\gf-config.xml)"; //ok
    
    std::filesystem::path p1( strFilePath1 ); //filesystem是 C++17标准
    if (filesystem::exists(p1)){
        std::cout << "exists" << std::endl;
    }else{
        std::cout << "not exists" << std::endl;
    }
    
    std::ifstream infstream( strFilePath1, ios::in | ios::binary);
    if(infstream.is_open())
    {
        char buf[1024] { 0 };
        memset(buf, 0, sizeof(buf));
    
        while (!infstream.eof())
        {
            infstream.getline(buf, 1024);
            std::cout << buf << std::endl;
        }
    
        infstream.close();
    }
    else
    {
        std::cout << "open file failed." << std::endl;
    }
    
  • filesystem 文件系统

  • chrono 时间

  • regex 正则表达式

以下内容, 移至 C++11并发编程 中做介绍

  • atomic 原子操作

    https://en.cppreference.com/w/cpp/atomic

    关于std::memory_order: https://www.cnblogs.com/lizhanzhe/p/10893016.html

  • std::thread

  • std::mutex

  • std::future

  • std::atomic

  • std::async


/**
*Date: 2019/11/30 13:24
*Author:yqq
*Descriptions:

	C++11  C++14  C++17 的一些新的特性

*/
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS  
#endif
#include <cstdio>
#include <iostream>
#include <vector>
#include <array>
#include <complex>

#define  BOOST_TEST_MAIN
#include "boost/algorithm/string.hpp"
#include "boost/format.hpp"
#include "boost/test/included/unit_test.hpp"


using namespace std;



BOOST_AUTO_TEST_SUITE(test_cpp11)

BOOST_AUTO_TEST_CASE(test_char16_t)
{
	const char16_t* ch16Chinese = u"中文のああㅝㅒㅖㄸЩПЁξζ∰㏒";
	const char32_t* ch32Chinese = U"中文のああㅝㅒㅖㄸЩПЁξζ∰㏒";
	const wchar_t* wchChinese = L"中文のああㅝㅒㅖㄸЩПЁξζ∰㏒";
	std::wcout << ch16Chinese << std::endl;
	std::wcout << ch32Chinese << std::endl;
	std::cout << "--------" << std::endl;
	std::wcout << wchChinese << std::endl;
	wprintf(wchChinese);

	std::cout << "hello" << std::endl;
}


BOOST_AUTO_TEST_CASE(test_uniforminitialize)
{

	int d{ 10 };
	char ch {90};


	std::vector<int> a1{ 100, 99, 123 };
	std::cout << "size : " << a1.size() << std::endl;
	for (auto item : a1) {
		std::cout << item << std::endl;
	}
	
}


struct CTemp
{
	//CTemp(std::initializer_list<int> &initList) //error
	CTemp(std::initializer_list<int> initList) //ok
	{
		for (auto item : initList)
		{
			m_vctNumbers.push_back(item);
		}

		/*m_vctNumbers(initList);*/ //error
	}

	~CTemp() {}


	void Show()
	{
		for (auto item : m_vctNumbers)
		{
			std::cout << item << std::endl;
		}
	}

	//void Set(std::initializer_list<int>& ilstArgs) //不支持引用方式
	//void Set(std::initializer_list<int> *ilstArgs) //不支持指针
	void Set(std::initializer_list<int> ilstArgs)
	{
		m_vctNumbers.clear();
		//for (auto item : *ilstArgs)
		for (auto item : ilstArgs)
		{
			m_vctNumbers.push_back(item);
		}
	}

	std::vector<int> m_vctNumbers;
};



BOOST_AUTO_TEST_CASE(test_initialize_list)
{
	//该语法只能用于构造函数, 但是initializer_list可以当做模板来用
	CTemp  tmp{ 3, 9, 2, 88, 12, 93 }; 
	
	tmp.Show();

	tmp.Set({1, 3, 9, -134});

	tmp.Show();
}


template <typename T>
void MyTest(T a, T b)
{
	typedef std::array<T, 10> arr10;
	using arr11 = std::array<T, 11>;

	arr10 arrTst;
	arrTst[0] = a;
	arrTst[9] = b;

	std::cout << arrTst[9] << std::endl;

	arr11 arr11Tst;
	arr11Tst[0] = a;
	arr11Tst[10] = b;
	std::cout << arr11Tst[10] << std::endl;

}



template < typename T >
using arr20 = std::array<T, 20>;
//typedef arr20 = std::array<T, 20>; //错误, typedef不支持

BOOST_AUTO_TEST_CASE(test_using)
{

	//使用 typedef 取别名
	typedef std::vector<int>::iterator   vctit;
	using vctit2 = std::vector<int>::iterator ;


	std::vector<int> vctTst{1, 39, 99};
	vctit itBegin = vctTst.begin();
	vctit2 itBegin2 = vctTst.begin();
	std::cout << (itBegin == itBegin2) << std::endl;
	std::cout << *itBegin << std::endl;


	MyTest<int>( 7, 9);


	arr20<double> arr20Test{ 0.99923, 1.342, 9 };
	for (auto item : arr20Test)
	{
		std::cout << item << std::endl;
	}
}



template <typename T, typename U>
auto MyFunc(T t, U u) -> decltype(t + u)
{
	return t + u;
}

struct CPear
{
	CPear(std::string strName) : m_strName(strName)
	{
	}
	
	std::string m_strName;
};

struct CPearApple
{
	CPearApple(std::string strName) :m_strName(strName)
	{

	}

	std::string m_strName;
};

struct CApple
{
	CApple(std::string strName) : m_strName(strName)
	{

	}


	CPearApple operator+ (const CPear& pear)
	{
		return CPearApple(pear.m_strName + m_strName);
	}

	std::string m_strName;
};


BOOST_AUTO_TEST_CASE(test_functionreturntype)
{
	std::complex a(1, -2);
	std::complex  b(2, -3);

	auto c  =  MyFunc( a , b );
	std::cout << c << std::endl;

	CPear pear("pear");
	CApple apple("apple");
	auto pearApple = MyFunc(apple, pear);


	std::cout << pearApple.m_strName << std::endl;

}
//




BOOST_AUTO_TEST_CASE(test_testlabdafunctype)
{

	auto func = [](int a, double b, const std::string& strTmp)->std::string {
		boost::format fmt("%1%  %2%  %3%");
		fmt % a% b% strTmp;
		return fmt.str();
	};

	/*
	auto func2 = [](int a, double b, const std::string& strTmp)->std::string {
		char buf[1024] = { 0 };
		memset(buf, 0, sizeof(buf));
		sprintf_s(buf, "%d %.8f %s", a, b, strTmp.c_str());
		return std::string(buf);
	};
	*/

	std::map<int, decltype(func)> fucMap;

	fucMap.insert( std::make_pair(0,   func) );
	//fucMap.insert( std::make_pair(1, );

	auto it = fucMap.find(0);
	BOOST_CHECK_EQUAL( fucMap.end()== it, false);
	std::cout << it->second(10, 1.23, std::string("hello")) << std::endl;

}



class MyComplex
{
public:
	MyComplex(int ir, int im = 0)
		: _m_ir(ir), _m_im(im)
	{
		_m_ino = 55 + ir;
	}

	//C++的数据限制是 "类" 级别的, 而不是对象级别, 
	//所以同一类的  一个对象 再成员函数中可以修改 另一个对象的私钥或保护成员
	MyComplex & operator + (const MyComplex& cplx)
	{
		_m_ir += cplx._m_ir;
		_m_im += cplx._m_im;
		std::cout << cplx._m_ino << std::endl;
		return *this;
	}


protected:
	int _m_ir;
	int _m_im;

private:
	int _m_ino;
};


class MyComplexEx
{
public:
	explicit MyComplexEx(int ir, int im = 0)
		: _m_ir(ir), _m_im(im)
	{
		_m_ino = 55 + ir;
	}

	//C++的数据限制是 "类" 级别的, 而不是对象级别, 
	//所以同一类的  一个对象 再成员函数中可以修改 另一个对象的私钥或保护成员
	MyComplexEx& operator + (const MyComplexEx& cplx)
	{
		_m_ir += cplx._m_ir;
		_m_im += cplx._m_im;
		std::cout << cplx._m_ino << std::endl;
		return *this;
	}


protected:
	int _m_ir;
	int _m_im;

private:
	int _m_ino;
};

BOOST_AUTO_TEST_CASE(test_explicit)
{
	MyComplex  mcplx(5, -1);
	mcplx = mcplx + 5;   //这样是可以的, 编译做了隐式转换
	//_m_ir = 10
	//_m_im
	MyComplexEx  mcplxEx(5, -1);
	//mcplxEx = mcplxEx + 5;   //这样是不可以的, 显示地限制了隐式转换
	
}


BOOST_AUTO_TEST_SUITE_END()


可变参数模板

/**
*Date: 2019/12/21  14:27
*Author:yqq
*Descriptions:  C++11 可变参数模板
*/
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS  
#endif
#include <cstdio>
#include <iostream>
#include <vector>
#include <array>
#include <complex>
#include <algorithm>
#include <ctime>

#define  BOOST_TEST_MAIN
#include "boost/algorithm/string.hpp"
#include "boost/format.hpp"
#include "boost/test/included/unit_test.hpp"



BOOST_AUTO_TEST_SUITE(test_cpp11)



template<typename T>
void PlainPrint(const T& arg)
{
	std::cout << arg << std::endl;
}

//函数模板不存在 "偏特化"
/*
template<>
void PlainPrint(const std::complex& cplx)
{
	std::cout << "复数: " << cplx << std::endl;
}
*/




//递归结束
void XPrint()
{
}


template< typename T, typename ...Types>
void XPrint(const T& first,  const Types&... otherArgs)
{
	PlainPrint(first);
	XPrint( otherArgs... );
}



BOOST_AUTO_TEST_CASE(test_variadic_templates)
{
	std::cout << "hello  ............" << std::endl;

	XPrint(2, 5.231, std::string("hello"), "niuniu", std::complex(5, 1));

}






//实现编译时期的求最大值得函数
//#define  mymax( a, b )   ( a > b ? a : b )


#ifdef max
#undef max
#endif


int mymaximum(int n) //递归结束
{
	return n;
}

template <typename ...Args>
int mymaximum(int nfirst, const Args&... arguments)
{
	return std::max(nfirst, mymaximum(arguments...));
}


BOOST_AUTO_TEST_CASE(test_variadic_maximum)
{

	std::cout << "maximum is : " <<
		mymaximum(9, 1, -1, 22, -12, 10, 11, -9, 5, -23, 19, 21, 22)
		<< std::endl;

	//std::cout << mymax(9, 10) << std::endl;
   //std::cout <<	std::max( 9, 10 ) << std::endl;

}




BOOST_AUTO_TEST_CASE(test_move)
{
	std::vector <std::string>   vctStrs;

	const int iTestCount = 500;

	{


#ifdef _WIN32
		DWORD   dwStart = ::GetTickCount();
#else
		clock_t  clkStart = clock();
#endif


		for (int i = 0; i < iTestCount; i++)
		{
			//vctStrs.push_back( std::move( std::string("helllo")  )); //默认使用 push_back(T&&)


			std::string strTmp("hello");

			vctStrs.push_back(strTmp); //使用   push_back(T &)

		}

#ifdef _WIN32
		DWORD   dwEnd = ::GetTickCount();
		std::cout << "duration: " << dwEnd - dwStart << std::endl;
#else
		clock_t  clkEnd = clock();
		std::cout << "duration: " << clkEnd - clkStart << std::endl;
#endif

	}


	{

#ifdef _WIN32
		DWORD   dwStart = ::GetTickCount();
#else
		clock_t  clkStart = clock();
#endif

		for (int i = 0; i < iTestCount; i++)
		{
			//std::string strTmp("hello");

			vctStrs.push_back(std::move(std::string("hello"))); // 使用 push_back(T&& )
		}


#ifdef _WIN32
		DWORD   dwEnd = ::GetTickCount();
		std::cout << "duration: " << dwEnd - dwStart << std::endl;
#else
		clock_t  clkEnd = clock();
		std::cout << "duration: " << clkEnd - clkStart << std::endl;
#endif

	}

}


BOOST_AUTO_TEST_CASE(test_initializer_list)
{

	std::vector<int> vctInts({92, 12, 39, 46, 92, 84, -1, 0, -234});
	for (const auto& item : vctInts)
	{
		std::cout << item << std::endl;
	}


}


BOOST_AUTO_TEST_SUITE_END()



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
王桂林老师 C++11 14 17 课件 1. Why C++ 11..........................................................................................- 1 - 1.1. C++ History...................................................................................................- 1 - 1.2. Modern C++.................................................................................................. - 1 - 1.3. 功能一览...................................................................................................... - 2 - 1.4. Why ModernC++.......................................................................................... - 2 - 2. More Concise.......................................................................................- 3 - 2.1. nullptr............................................................................................................ - 3 - 2.1.1. 入参............................................................................................................................... - 3 - 2.1.2. 返值............................................................................................................................... - 3 - 2.2. override..........................................................................................................- 4 - 2.2.1. 语义............................................................................................................................... - 4 - 2.2.2. 示例............................................................................................................................... - 4 - 2.3. final................................................................................................................- 5 - 2.3.1. 语义............................................................................................................................... - 5 - 2.3.2. 示例............................................................................................................................... - 5 - 2.3.3. 意义.........................................

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值