您的位置:首页 > 编程语言 > C语言/C++

C++ 11/14 1

2017-04-26 10:55 155 查看
variadic template parameter

Ranged for

initializer list

Explicit Ctor

补充 1.对象序列化(boost) 2. base64 编码 3.constexpr,auto,decltype 关键字 4. OOA,OOD,OOP,ATL概念 5.bitset 6.内部连接外部连接

variadic template parameter

实现不定类型数量参数打印

void print(){}//结束条件
template<typename T,typename... Types>
void print(const T& firstarg, const Types&... args)
{
cout << firstargs << endl;
print(args);
}
test: print(1,1.9,"aas");


实现万用hash

class CustomerHash {
public:
std::size_t operator()(const Customer& c) const {
return hash_val(c.fname, c.lname, c.no);
}
};

//1.
template<typename... types>//不定参模板
inline size_t hash_val(const Types&... args) {
size_t seed=0;
hash_val(seed,args...);
return seed;
}
//2.
template<typename T, typename... Types>
inline void hash_val(size_t& seed, const T& val,const Types&... args) {
hash_combine(seed,val);
hash_val(seed,args);
}
//3.结束函数
template<typename T>
inline void hash_val(size_t& seed, const T& val)
{
hash_combine(seed,val);
}

template<typename T>
inline void hash_combine(size_t& seed, const T&val){
seed^=std::hash<T>()(val) +0x9e3779b9 + (seed<<6) +(seed>>2);//0x9e3779b9 黄金分割率
}


实现tuple

template<typename... Values> class tuple;
template<> class tuple<> {};

template<typename Head, typename... Tail>
class tuple<Head,Tail...>:private tuple<Tail...>
{
typedef tuple<Tail...> inherited;
public:
tuple(){}
tuple(Head v, Tail...vtail):m_head(head), inherited(vtail...) {}
Head head() {return m_head;}
inherited& tail() {return *this;}
protected:
Head m_head;
};
//example
tuple<int, float, string> t(41, 6.3, "nico");
t.head();//得到41
t.tail();// 得到inherited 类型tail
t.tail().head();// 得到6.3


构造时从右往左构造tuple< > – >tuple < string >– >tuple< float,string >

Ranged for

形式 for (decl : coll) {

statement

}

vector<int> vec {1,2,3,4};
for (auto elem: vex){
cout << elem << endl;
}

for(auto& elem : vec){
elem *= 2;
}
for (int i :{1,2,3,4,5}){
cout << i << endl;
}


initializer list

int i;//无默认值
int j{}//有默认值
int* p;//无默认值
int* p{};//有默认值
int p{5.3};//error 不允许narrow


编译器自动将{}构造为一个initilizer_list 并将其内容分发给相应的构造函数。当不存在initializer_list 构造函数时,{} 中的初始化内容将被对应为为已有的对应构造函数中。若还不满足则编译失败。

#include <initializer_list>
class TestInitializerList
{
public:
TestInitializerList(int a,int b):m_a(a),m_b(b){
}
TestInitializerList(std::initializer_list<int> vals){
for (auto item :vals)
cout << item;
}
};
Test: TestInitializerList t1 {1,2};
TestInitializerList t2 {1,2,3,4};
//当两个构造函数都存在时调用第二个,当只有第一个构造函数时t1调用第一个t2编译失败,此时修改t2{{1,2},{3,4}}可以通过


原理: 编译器自动构造一个array< T ,n >自动调用initializer_list实现上述功能。

实现:

template <class _E>
class initializer_list
{
public:
typedef _E value_type;
typedef const _E& reference;
typedef const _E& const_reference;
typedef size_t size_type;
typedef const _E* iterator;
typedef const _E* const_iterator;
private:
iterator _M_array;
size_type _M_len;
// Compiler can call a private constructor
constexpr initializer_list(const_iterator __a, size_type __l):_M_array(__a),_M_len(__l){}
public:
constexpr initializer_list():_M_array(0),_M_len(0) noexcept {}
constexpr size_type size() const noexcept {return _M_len;}
constexpr const_iterator begin() const noexcept {return _M_array;}
constexpr const_iterator end() {return begin() + _M_len;}
};


C++11中vector,deque,array,set,list,foward_list,map均提供了这种初始化方式,包括insert,operator=,assign等。

Explicit Ctor

#include <initializer_list>
class TestInitializerList
{
public:
explicit TestInitializerList(int a,int b,int c):m_a(a),m_b(b){
}
TestInitializerList(std::initializer_list<int> vals){
for (auto item :vals)
cout << item;
}
};
Test: TestInitializerList t1 {1,2,3};


此时编译失败转化。(vs2017可以编译通过)(此处根据编译器实现不同而不同vs 2017 只要存在initializer_list 就会调用initializer_list 版本构造函数,)

补充 1.对象序列化(boost) 2. base64 编码 3.constexpr,auto,decltype 关键字 4. OOA,OOD,OOP,ATL概念 5.bitset 6.内部连接外部连接

1.对象序列化

boost serialization 库

#inlcude <boost/archive/text_iarchive.hpp>
#inlcude <boost/archive/text_oarchive.hpp>
#include <iostream>
#include <fstream>
void save()
{
std::ofstream file("archive.txt");
boost::archive::text_oarchive oa(file);
std::string s = "save test\n";
oa & s; // samw with oa << s;
}

void load()
{
std::ifstream file("archive");
boost::archive::text_iarchive ia(file)
std::string s;
ia & s;//same with ia >> s;
}

若想保存到XML 中则头文件更换为xml_iarchive.hpp/xml_oarchive.hpp
oa & BOOST_SERIALIZATION_NVP(s);
ia & BOOST_SERIALIZATION_NVP(s);


转存数组需要提前指定数组大小。转存STL 容器不需要指定大小,转存自定义类需要在类中定义一个serialize方法供归档时调用

template<class Archive>
void serialize(Archive& archive,const unsigned int version)
{
archive & BOOST_SERIALIZATION_NVP(private_data);
...
}


或者非侵入性版本

template<class Archive>
void serialize(Archive& archive,date& d, const unsigned int version)
{
archive & BOOST_SERIALIZATION_NVP(private_data);
...
}


2.base64编码

参考:

http://www.cnblogs.com/chengmo/archive/2014/05/18/3735917.html

3.constexpr

const 变量的初始化可以延迟到运行时,而 constexpr 变量必须在编译时进行初始化。

在C++11中,我们可以声明某些函数是常量表达式,这样的函数必须在编译期间计算出它们的值,这样的函数必须满足以下条件:

返回值和参数必须是Literal类型

函数体必须只包含一个return语句

函数提可以包含其他的语句,但是这些语句不能在运行期起作用

函数可以不返回常量,但是在调用的时候实参必须传入常量表达式

http://blog.csdn.net/csxiaoshui/article/details/39473419

auto

参考:

http://blog.csdn.net/huang_xw/article/details/8760403

dcltype:

参考:

http://blog.csdn.net/yshe_xun/article/details/7315135

4. OOA,OOD,OOP,ATL概念

参考:http://www.cnblogs.com/niexiaobo/p/4884706.html

http://blog.csdn.net/xdrt81y/article/details/17143135

5.bitset

http://blog.csdn.net/qll125596718/article/details/6901935

http://blog.csdn.net/u012069890/article/details/59108840

6.内部连接外部连接

http://blog.csdn.net/xiexievv/article/details/8491494

http://developer.51cto.com/art/201107/277364.htm

http://bbs.csdn.net/topics/390495702

http://blog.csdn.net/sruru/article/details/7951019
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言