C++ 11/14 2
来源:互联网 发布:山东卫生厅网络直报 编辑:程序博客网 时间:2024/06/18 12:39
- 关键字 =delete,=default,using, noexcept, override, final, decltype,
- lambda 函数
- variadic template parameter
- 补充 1.make语法,2.swap, 3.exception,4.set 实现,5.remove_if meta programming. 6.虚继承,7.多继承,8.memcpy(),memset(),memcmp()9. 模版内模版
关键字 =delete,=default,using, noexcept, override, final, decltype,
1.=default 通常对于 默认构造函数,拷贝构造函数,拷贝赋值构造函数,析构函数,+ 对应的move 构造函数,如果自定义了改函数则编译器不会自动产生该构造函数。 但是为了减轻开发负担在需要默认构造函数时可以= default指定让编译器帮忙产生该类型构造函数,如果不想要该类型构造函数 可以=delete。 =default,=delete 可以在类体内部和外部
inline widget& widget::operator=(const widget&) = default;
=delete 可以用在函数提上表示禁止重载某一类函数
bool isLucky(int number); // original functionbool isLucky(char) = delete; // reject charsbool isLucky(bool) = delete; // reject boolsbool isLucky(double) = delete; // reject doubles and float
可以用来指定禁止某类模版偏特化
class Widget {public: template<typename T> void processPointer(T* ptr) { … }};template<> void Widget::processPointer<void>(void*) = delete; // still public, but deleted
参考:
之前的实现形式时将该方法或特化声明在private中但不实现。
想使某一类class不自动产生 拷贝构造,拷贝赋值,可以定义一个uncopyable class 将其 拷贝构造,拷贝赋值放在private中可以避免其子类实现默认或非默认拷贝构造,拷贝赋值构造函数。
http://www.cnblogs.com/xinxue/p/5503836.html
2. using
//c++98typedef std::unique_ptr<std::unordered_map<std::string,std::string>> Uptrmap;//same with C++ 11using Uptrmap = std::unique_ptr<std::unordered_map<std::string,std::string>>;typedef void (*Fn) (int, const std::string&);//same withusing Fn = void (*)(int, const std::string&);//容易识别Fn为其别名//以下为区别 typedef cannot be a templatetemplate <typename T>using Vec = std::vector<T,Myalloc<T>>Vec<int> col;//可以编译通过template<typename T>typedef std::vector<T,Myalloc<T>> Vec;//编译失败,error: a typedef cannot be a template//只能typedef std:::vector<int,Myalloc<int>> Vec;//或者template <typename T>clss Vec { typedef std::vector<T,MyAalloc<T>> type;};Vec<int>::type col;//用在模板类内部或者进行参数传递时必须加上typename 用以指定为类型。//即typedef不能直接作为模板使用
using value_type = T;//用在类内部代替typedef T value_type;
使用 using 别名后不能特化也不能偏特化
1.typedefs don’t support templatization, but alias declarations do.
2.Alias templates avoid the “::type” suffix and, in templates, the “typename” prefix often required to refer to typedefs.
3.C++14 offers alias templates for all the C++11 type traits transformations.
参考:
https://zhuanlan.zhihu.com/p/21264013
3.noexcept
从语法上讲,noexcept修饰符有两种形式,一种就是简单地在函数声明后加上noexcept关键字。比如:
void excpt_func() noexcept;
另外一种则可以接受一个常量表达式作为参数,如下所示:
void excpt_func() noexcept (常量表达式);
常量表达式的结果会被转换成一个bool类型的值。该值为true,表示函数不会抛出异常,反之,则有可能抛出异常。这里,不带常量表达式的noexcept相当于声明了noexcept(true),即不会抛出异常。
noexcept形如其名地,表示其修饰的函数不会抛出异常。不过与throw()动态异常声明不同的是,在C++11中如果noexcept修饰的函数抛出了异常,编译器可以选择直接调用std::terminate()函数来终止程序的运行,这比基于异常机制的throw()在效率上会高一些。这是因为异常机制会带来一些额外开销,比如函数抛出异常,会导致函数栈被依次地展开(unwind),并依帧调用在本帧中已构造的自动变量的析构函数等。
#include <iostream>using namespace std;void Throw() { throw 1; }void NoBlockThrow() { Throw(); }void BlockThrow() noexcept { Throw(); }int main() { try { Throw(); } catch(...) { cout << "Found throw." << endl; // Found throw. } try { NoBlockThrow(); } catch(...) { cout << "Throw is not blocked." << endl; // Throw is not blocked. } try { BlockThrow(); // terminate called after throwing an instance of 'int' } catch(...) { cout << "Found throw 1." << endl; }}//
BlockThrow() 会直接 terminate不会被catch
而noexcept作为一个操作符时,通常可以用于模板。比如:
template <class T> void fun() noexcept(noexcept(T())) {}
这里,fun函数是否是一个noexcept的函数,将由T()表达式是否会抛出异常所决定。这里的第二个noexcept就是一个noexcept操作符。当其参数是一个有可能抛出异常的表达式的时候,其返回值为false,反之为true(实际noexcept参数返回false还包括一些情况,这里就不展开讲了)。这样一来,我们就可以使模板函数根据条件实现noexcept修饰的版本或无noexcept修饰的版本。从泛型编程的角度看来,这样的设计保证了关于“函数是否抛出异常”这样的问题可以通过表达式进行推导。因此这也可以视作C++11为了更好地支持泛型编程而引入的特性。
比如在C++98中,存在着使用throw()来声明不抛出异常的函数。
template<class T> class A { public: static constexpr T min() throw() { return T(); } static constexpr T max() throw() { return T(); } static constexpr T lowest() throw() { return T(); }...而在C++11中,则使用noexcept来替换throw()。template<class T> class A { public: static constexpr T min() noexcept { return T(); } static constexpr T max() noexcept { return T(); } static constexpr T lowest() noexcept { return T(); }...又比如,在C++98中,new可能会包含一些抛出的std::bad_alloc异常。void* operator new(std::size_t) throw(std::bad_alloc);void* operator new[](std::size_t) throw(std::bad_alloc);而在C++11中,则使用noexcept(false)来进行替代。void* operator new(std::size_t) noexcept(false);void* operator new[](std::size_t) noexcept(false);当然,noexcept更大的作用是保证应用程序的安全。比如一个类析构函数不应该抛出异常,那么对于常被析构函数调用的delete函数来说,C++11默认将delete函数设置成noexcept,就可以提高应用程序的安全性。void operator delete(void*) noexcept;void operator delete[](void*) noexcept;
特别的 you need inform C++(specially std::vector,deque)that your move constructor and destructor does not throw. Then the move constructor will be called when vector grows. if the constructor is not noexcept std::vector cannot use it. since then it cannot ensure the exception guranteesdemnaded by the standard.
参考 :
http://book.2cto.com/201306/25351.html
4.override
描述:override保留字表示当前函数重写了基类的虚函数。
目的:1.在函数比较多的情况下可以提示读者某个函数重写了基类虚函数(表示这个虚函数是从基类继承,不是派生类自己定义的);2.强制编译器检查某个函数是否重写基类虚函数,如果没有则报错。
用法:在类的成员函数参数列表后面添加该关键字既可。
例子:
class Base {
virtual void f();
};
class Derived : public Base {
void f() override; // 表示派生类重写基类虚函数f
void F() override;//错误:函数F没有重写基类任何虚函数
};
注意:override只是C++保留字,不是关键字,这意味着只有在正确的使用位置,oerride才启“关键字”的作用,其他地方可以作为标志符(如:int override;是合法的)。
相关:override还有一个姊妹保留字final。
参考:
http://www.cnblogs.com/kyxyes/p/3995937.html
5.final
用在类上表示不能被继承,用在 virtual func上表示不能被重写。
参考:
http://blog.csdn.net/nighsen/article/details/6363370
6.decltype
let compiler find the type of an expression. semantic same with pyhon type(),semantic typeof()
用法1 declare return type
template <typename T1, typename T2>auto add(T1 a, T2 b)->decltype(a+b) {}
用法2。用于meta programming
typedef typename decltype(obj)::iterator iType;
用法3.use to pass the type of lambda func
auto cmp = [](const Person& p1, const Person& p2){ return p1.name() < p2.name();}//此时想获得lambda type 用于设定set的cmp funcstd::set<Person, decltype(cmp)> coll(type);
Lambda 函数
define inline function can be used as a parameter or local obj.
format: []()mutalbe throwspec ->retType{}
lambda have no default constructor and no assignment operator
1. [] 不截取任何变量
2. [&} 截取外部作用域中所有变量,并作为引用在函数体中使用
3. [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
4. [=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
5. [bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
6. [x, &y] x按值传递,y按引用传递
7. [this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
C++ 14以后可以使用 template
template <typename T>a = [=](const T& n) {cout << T << endl;}a<int>(1)
注意lmabda在没有捕获外界变量的情况下可以直接转换为函数指针,一旦捕获了就只能转换function<…> obj;
参考:
http://blog.csdn.net/booirror/article/details/26973611
http://blog.csdn.net/u010102854/article/details/52857312
区别 function http://blog.163.com/lvan100@yeah/blog/static/6811721420127511289750/
补充 : 将析构函数定义为私有意味着只能在堆上new对象并且使用者需要自己负责destroy对象。这是由于c++语言为静态语言在编译时需要对所有静态函数检查可入性,在栈上创建的不具有可入性。
参考:http://blog.csdn.net/zyq522376829/article/details/48438037
variadic template parameter
补充 求最大值两种方式1.initializer-list
template<typename _Tp>inline _Tp max(initializer_list<_Tp> __l){ return *max_element(__l.begin(),__l.end());}template<typename _ForwardIterator>inline _ForwardIteratormax(_ForwardIterator __first,_ForwardIterator __last){ return __max_element(__first,__last,__iter_less_iter());}template<typename _ForwardIterator, typename _Compare>_ForwardIterator_max_element(_ForwardIterator __First, _ForwardIterator __Last,_Compare __comp){ if(__first == __last) return __first; ForwardIterator __result = __first; while(++__first != __last) if (__comp(__result,__first)) __result = __first; return __result;}inline _Iter_less_iter(){ return _Iter_less_iter();}
- variadic template parameters
int maximum(int n){ return n;}template<typename... Args>int maximum(int n, Args... args){ return std::max(n,maximum(args...));}
print tuple
template <typename... Args>ostream& operator << (ostream& os, const tuple<Args...>& t){ os << "["; PRINT_TUPLE<0,sizeof...(Args),Args...>::print(os,t); return os << "]"; }template<int IDX,int MAX,typename... Args>struct PRINT_TUPLE{ static void print(ostream& os, const tuple<Args...>& t ){ os << get<IDX>(t) << (IDX+1)==MAX?"":","; PRINT_TUPLE<IDX+1,MAX,Args...>(os,t); }};template <int MAX, typename...Args>struct PRINT_TUPLE<MAX,MAX,Args...>{ static void print (std::ostream& os,const tuple<Args...>& t){}};//end statment
- 补充 1.make语法,2.swap, 3.exception,4.set 实现,5.remove_if meta programming. 6.虚继承,7.多继承,8.memcpy(),memset(),memcmp()9. 模版内模版
##
1. make 语法
参考:
http://www.kuqin.com/shuoit/20150225/344882.html
http://lpn520.iteye.com/blog/774919
2.swap
参考:
http://www.cnblogs.com/xloogson/p/3360847.html
3.exception
参考:
http://blog.csdn.net/zkreats/article/details/50550786
http://www.cnblogs.com/crazyacking/p/4951638.html
4.set实现
set 是一个rb_tree 的adaptor具体实现如GNU4.9下
template <typename _Key, typename _Compare = s s td::less<_Key>,typename _Allloc = std::allocator<_Key>>class set { typedef typename _Alloc::value_type _Alloc_value_type;public: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; typedef _Alloc allocator_type;private: typedef typename __gnu_cxx::__alooc_traits<_Alloc>::template rebind<_Key>::other _Key_alloc_type; typedef _Rb_tree<key_type, value_type, Identity<value_type>, key_compare, _Key_alloc_type> _Rep_type; _Rep_type _M_t;//adaptor define rb_tree typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;public: //Iterator relaited typedef typedef typename _Alloc_traits::pointer pointer; typedef typename _Alloc_traits::const_pointer const_pointer; typedef typename _Alloc_traits::reference reference; typedef typename _Alloc_traits::const_reference const_reference; typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::const_reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_ierator const_reverse_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; set():_M_t(){} explicit set(const _Compare& __comp, const allocator_type& __a = allocator_type()) :_M_t(__comp,__key_alloc_type(__a)){} .... //C++11 set(set&& __x) noexcept(is_nothrow_copy_constructible<_Compare>::value) :_M_t(std::move(__x._M_t)){} set(initializer_list<value_type> __l, const allocator_type& __a = allocator_type()) :_M_t(__comp,_Key_alloc_type(__a)) //所有操作均是调用rb_tree内来实现};
使用:
#include <iostream>#include <set>bool fncomp (int lhs, int rhs) {return lhs<rhs;}struct classcomp { bool operator() (const int& lhs, const int& rhs) const {return lhs<rhs;}};int main (){ std::set<int> first; // empty set of ints int myints[]= {10,20,30,40,50}; std::set<int> second (myints,myints+5); // range std::set<int> third (second); // a copy of second std::set<int> fourth (second.begin(), second.end()); // iterator ctor. std::set<int,classcomp> fifth; // class as Compare bool(*fn_pt)(int,int) = fncomp; std::set<int,bool(*)(int,int)> sixth (fn_pt); // function pointer as Compare return 0;}
参考:http://www.cplusplus.com/reference/set/set/set/
http://blog.csdn.net/jinzhilong580231/article/details/8666877
5.remove_if meta programming
http://blog.csdn.net/tianshuai1111/article/details/7674327
partial_sum 实现Fib
array<int, 10> input;//不会默认初始化array<int,10> result;for(int i = 0; i < input.size();i++){ input[i] = i;//replace(iv.begin(),iv.end(),6,3);初始化可以用replace result[i] = 0;}partial_sum(input.begin(),input.end(),result.begin(),plus2<int>());//accumulate()int my_sum(int a, int b){return a + b;}
模板实现编译其期间Fib
template<int N>class Fib {public: enum{Result = Fib<N-1>::Result + Fib<N-2>::Result};};template<>Fib<1>class Fib { enum{Result = 1};};template<>Fib<0>class Fib{ enum{Result = 0};}
累加vector使用lambda
std::for_each(vector.begin(), vector.end(), [&] (int n) { sum_of_elems += n;});
补充python 实现fib http://blog.csdn.net/buaa_shang/article/details/8283309
remove_if 使用
// remove_if example#include <iostream> // std::cout#include <algorithm> // std::remove_ifbool IsOdd (int i) { return ((i%2)==1); }int main () { int myints[] = {1,2,3,4,5,6,7,8,9}; // 1 2 3 4 5 6 7 8 9 // bounds of range: int* pbegin = myints; // ^ int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^ pend = std::remove_if (pbegin, pend, IsOdd); // 2 4 6 8 ? ? ? ? ? // ^ ^ std::cout << "the range contains:"; for (int* p=pbegin; p!=pend; ++p) std::cout << ' ' << *p; std::cout << '\n'; return 0;}
6.虚继承,多继承
https://www.oschina.net/translate/cpp-virtual-inheritance
http://blog.csdn.net/wangxingbao4227/article/details/6772579
http://blog.csdn.net/u013630349/article/details/47057929
7.memcpy(),memset(),memcmp()
注意区分POD(plain old data)
http://www.cnblogs.com/jingliming/p/4737409.html
http://www.cnblogs.com/mayingkun/p/3234137.html
- 模版内模版
非类型实参参考:http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html
http://www.cnblogs.com/gw811/archive/2012/10/25/2736224.html
重点参考http://www.cnblogs.com/assemble8086/archive/2011/10/02/2198308.html
- C - The C Answer (2nd Edition) - Exercise 1-14
- 11-linux-c基础2
- C - The C Answer (2nd Edition) - Exercise 1-11
- 求1+2+...+n[C/C++/C#]
- C(11)
- 11C
- C++(2)
- C++--2
- C#(2)
- C.2
- C++(2)
- C--2
- c++(2)
- C-2
- C++(2)
- C/C++_lesson9~14测试
- 【Deep C (and C++)】深入理解C/C++(2)
- 【Deep C (and C++)】深入理解C/C++(2)
- 子数组之和
- 库文件的链接问题
- webstrom使用心得
- ubuntu安装网易云云音乐
- Linux下file_struct以及文件描述符
- C++ 11/14 2
- win7 cmd 进入指定目录下
- 两数组的交
- leetcode-48. Rotate Image
- Python版本升级
- RAID实战
- 解决Spring MVC @ResponseBody返回中文字符串乱码问题
- 05 春申门下三千客,小杜城南五尺天
- leetcode 476 Number Complement