C++ 11/14 3
来源:互联网 发布:matlab绘制矩阵图 编辑:程序博客网 时间:2024/05/21 22:58
- Rvalue and Lvalue
- std::forward
- moveable string
- mutable
- constexpr
- 11 编程规范 1.类型处理
- auto /模板函数类型推导
Rvalue and Lvalue
Rvalue reference : a new reference type to solve unnecessary copy
Lvalue 可以出现在operator = 左右
Rvalue 之可以出现在operator = 右边(临时对象都是右值)
但是此时sting() = “aaa”, str1 + str2 = “aaa”可以编译违背上述定义
另一种说法可以取地址的都是左值。
以上两种说法属于学术之争不做深究。
补充函数返回值:
int foo() {return 1;}int x = foo()//okint(*)() x = &foo;//okint x = &foo()//error 此处语义为对foo()的返回值取地址,其返回值为一个右值无法取地址foo()= 7 //error
补充scott-meyers关于universal reference 解释
https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
归根结底需要推导的就是universal,给出足够信息不需要推导的就是rvalue。
std::forward
用来完美转发类型
// forward example#include <utility> // std::forward#include <iostream> // std::cout// function with lvalue and rvalue reference overloads:void overloaded (const int& x) {std::cout << "[lvalue]";}void overloaded (int&& x) {std::cout << "[rvalue]";}// function template taking rvalue reference to deduced type:template <class T> void fn (T&& x) { overloaded (x); // always an lvalue overloaded (std::forward<T>(x)); // rvalue if argument is rvalue}int main () { int a; std::cout << "calling fn with lvalue: "; fn (a); std::cout << '\n'; std::cout << "calling fn with rvalue: "; fn (0); std::cout << '\n'; return 0;}
move 源代码
template <typename _Tp> constexpr typename std::remove_referece<_Tp>::type&& move(_Tp&& __T)noexcept { return satic_cast<typename std::remove_reference<_Tp>::type&&> (__t); }
forward代码
template<typename _Tp>constexpr _Tp&& forward(typename std::remove_referece<_Tp>::type& _t)noexcept{ return static_cast<_Tp&&>(_t);}template <typename _Tp>constexpr _Tp&& forward(typename std::remove_referece<_Tp>::type&& __t)noexcept{ satic_assert(!std::islvaue_referece<_Tp>::value,"template argument substituting is an lvalue reference type"); return satic_cast<_Tp&&>(__t);}
参考:
http://shaoyuan1943.github.io/2016/03/26/explain-move-forward/
moveable string
class MoveableString{private: char* _data; size_t _len; void _init_data(const char* s){ _data =new char[_len+1]; memcpy(data,s,_len); _data[_len] = '\0';}public: MoveableString():_data(std::nullptr),_len(0){} MoveableString(const char* p ): _len(strlen(p){ _init_data(p); } MoveableString(const MoveableString& str):_len(str._len){ _init_data(str._data); } MoveableString(MoveableString&& str) noexcept:_data(str._data),_len(str._len){ str._len = 0; str._data = std::nullptr; } MoveableString& operator= (const MoveableString& str) { if (this != &str){ if(_data) delete[] _data; _len = str._len; _init_data(str._data); } return *this; } MoveableString& operator= (MoveableString&& str)noexcept { if(this != &str){ if(_data) delete[] _data; _data = str._data; _len = str._len; str._data = nullptr; str._len = 0; } return *this; } };//或者使用std::swap 实现也可以
mutable
const int * px = &x//指针本身可以改变,但是指向的内容不能更改int* const py = &y//指针本身不能只想别处,但是其内容可以更改class c{mutable int x;public: void f() const { this->x = 222;//此处想修改其值必须在x声明前面加上mutable }};
mutable一般只用在类内部,用在类外声明错误。
constexpr
constexpr是C++11中新增的关键字,其语义是“常量表达式”,也就是在编译期可求值的表达式。
最基础的常量表达式就是字面值或全局变量/函数的地址或sizeof等关键字返回的结果,而其它常量表达式都是由基础表达式通过各种确定的运算得到的。
constexpr值可用于enum、switch、数组长度等场合。
参考:
http://www.cnblogs.com/td15980891505/p/5137013.html
11 编程规范 1.类型处理
不确定用什么容器的时候首选vector
尽量避免隐式转型
推倒获取类型
template<typename>class ID;//无需定义仅为了引发编译错误,在编译期间显示变量类型ID<decltype(x)> xtype;//引发编译器错误,可以看到x 的type
aito d = [](const int *&p1, const int *&p2) {return *p1 <*p2;};
传递指针的引用否则会产生指针临时变量,无法真正赋值,c 中没有& 只能**
C++14lambda形参表可以用auto,11,不可以
vector<bool>????是vector 的一个bool特化 内部有一个代理类 bit_reference vector<boo> vb {true,false}; 对于auto v = vb[0]; decltype(v) 得到std::__Bit_reference 此时应该 auto v= static_cast<bool> vb[0];来正确得到vb[0]的类型 而不应该使用 bool v = vb[0];避免一切形式隐式转换 。
template<typename T>void func(T){}void func(T&){}传入实参若带const推导出来类型并不相同传入 const 会不会保留取决于传入的是不是* & ,*& 指向同一块内存 const保留,否则不保留。auto 推导和函数模板推导基本一样 除了initializer_list. auto 可以, 函数模板不可以。 && 万能引用 遇左则左遇右则右。 某种意义上说可以取址& 为左值 c/c++ 数组类型可以退化成指针 按引用传递则不会退化
萃取机来萃取数组长度
template<typename _type,std::size_t _size>constexpr auto traits_size(_type(&)[_size]) noexcept{ return _size;}//传入实参必须是数组不能使已经退化了的指针char a[] = {"123444"};std::size_t len_of_a = traits_size(a);
- C实现C(3)
- sublime text 3 c/c++(11) 以及sublimeclang配置 windows
- C(11)
- 11C
- C++(3)
- C.3
- C(3)
- C#(3)
- c++(3)
- C/C++_lesson9~14测试
- 【Deep C (and C++)】深入理解C/C++(3)
- 【Deep C (and C++)】深入理解C/C++(3)
- 【Deep C (and C++)】深入理解C/C++(3)
- C语言要点摘录(11~14)
- C/C++点滴 - 2010-11-3
- 【2015/11/14】 C学习日志_Day15 C的二进制代码分析
- MISRA C指导指南解读系列3(MISRA C规则11-19)
- C指针原理(14)-C指针基础
- log4j2 不使用配置文件,动态生成logger对象
- 不同操作系统下webstorm的使用---转载
- 备用
- 环信集成网页的im
- imadjust从用法到原理—Matlab灰度变换函数之一
- C++ 11/14 3
- gevent拾遗
- volatile关键字用法以及线程数据可见性的问题
- jquery获取所有选中的checkbox,判断CheckBox是否选中
- Md5加密
- 讲解视频质量,视频质量测试,主观客观评价视频质量
- Fel异常Check that your class path includes tools
- 23.struts2_输入验证
- (83)蓝图编辑器默认值选卡