一, C++11 新的特性

1, emplace_back 的使用

举例: std::vector 容器的使用

	std::vector<std::string> p;
    p.emplace_back("chenli");
    p.push_back("song");

看源码 push_back 模板

void push_back(value_type&& _Val)
		{	// insert by moving into element at end
		if (_Inside(_STD addressof(_Val)))   //先 检查数组中是否有数据  有数据就插入end , 
			{	// push back an element
			size_type _Idx = _STD addressof(_Val) - _Unfancy(this->_Myfirst());
			if (this->_Mylast() == this->_Myend())
				_Reserve(1);
			_Orphan_range(this->_Mylast(), this->_Mylast());
			this->_Getal().construct(_Unfancy(this->_Mylast()),
				_STD forward<value_type>(this->_Myfirst()[_Idx]));
			++this->_Mylast();
			}
		else  //没有数据  
			{	// push back a non-element
			if (this->_Mylast() == this->_Myend())
				_Reserve(1);
			_Orphan_range(this->_Mylast(), this->_Mylast());
			this->_Getal().construct(_Unfancy(this->_Mylast()),
				_STD forward<value_type>(_Val));
			++this->_Mylast();
			}
		}

push_back 是先检查是否有数据 然后在插入数据的

看一下 emplace_back

template<class... _Valty>
		void emplace_back(_Valty&&... _Val)   //直接插入end 
		{	// insert by moving into element at end
		if (this->_Mylast() == this->_Myend())
			_Reserve(1);
		_Orphan_range(this->_Mylast(), this->_Mylast());
		this->_Getal().construct(_Unfancy(this->_Mylast()),
			_STD forward<_Valty>(_Val)...);
		++this->_Mylast();
		}

emplace_back 是直接插入end 的 而且默认调用构造函数和析构函数

例子:



#include <vector>
#include <string>
#include <iostream>

struct President
{
    std::string name;
    std::string country;
    int year;

    President(std::string p_name, std::string p_country, int p_year)
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
    {
        std::cout << "I am being constructed.\n";
    }
    President(President&& other)
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being moved.\n";
    }
    President& operator=(const President& other) = default;
    ~President()
    {
        std::cout << "~President" << std::endl;
    }
};

int main()
{
    std::vector<President> elections;
    std::cout << "emplace_back:\n";
    elections.emplace_back("Nelson Mandela", "South Africa", 1994);

    std::vector<President> reElections;
    std::cout << "\npush_back:\n";
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));

    std::cout << "\nContents:\n";
    for (President const& president : elections) {
        std::cout << president.name << " was elected president of "
            << president.country << " in " << president.year << ".\n";
    }
    for (President const& president : reElections) {
        std::cout << president.name << " was re-elected president of "
            << president.country << " in " << president.year << ".\n";
    }

    system("pause");
    return 0;
}

C++11的新特性

2, C++ 的文件名中文 gb2312 -> utf-8

C++11 中 u8代表utf-8的格式

#include <cstdio>
#include <clocale>
#include <fstream>
#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
 
int main()
{
    std::setlocale(LC_ALL, "en_US.utf8");
    std::locale::global(std::locale("en_US.utf8"));
 
    fs::path p = fs::u8path(u8"要らない.txt");
 
    // native string representation can be used with OS APIs
    std::ofstream(p) << "File contents"; // this uses operator string()
    if(std::FILE* f = std::fopen(p.c_str(), "r")) {
        int ch;
        while((ch=fgetc(f))!= EOF) putchar(ch);
        std::fclose(f);
    }
 
    // multibyte and wide representation can be used for output
    std::cout.imbue(std::locale());
    std::cout << "\nFile name in narrow multibyte encoding: "
              << p.string() << '\n';
 
    std::wcerr.imbue(std::locale());
    std::wcerr << "File name in wide encoding: "
               << p.wstring() << '\n';
 
    fs::remove(p);
}

三, container

C++ 事件的使用 [std::multimap] -> 一对多的使用

api文档equal_range

在这里插入图片描述

#include <iostream>
#include <map>
 
int main()
{
    std::multimap<int, char> dict {
        {1, 'A'},
        {2, 'B'},
        {2, 'C'},
        {2, 'D'},
        {4, 'E'},
        {3, 'F'}
    };
 
    auto range = dict.equal_range(2);
 
    for (auto i = range.first; i != range.second; ++i)
    {
        std::cout << i->first << ": " << i->second << '\n';
    }
    
     std::cout << "==============  event 事件的使用 正确使用 container=================" << std::endl;
    
    std::pair<std::multimap<int, char>::const_iterator, std::multimap<int, char>::const_iterator> chen = dict.equal_range(2);
    for (std::multimap<int, char>::const_iterator it = chen.first; it != chen.second ; ++it )
    {
        std::cout << it->second << std::endl;
    }
}
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐