&&

  universal references(未定的引用类型),它必须被初始化,它是左值还是右值取决于它的初始化,如果&&被一个左值初始化,它就是一个左值;如果它被一个右值初始化,它就是一个右值;只有当发生自动类型推断时(如函数模板的类型自动推到,或auto关键字),&&才是一个universal references.

template<typename T>
void f(T&& param); //这里T的类型需要推导,所以&&是一个universal references f(10); //10是右值
int x = 10;
f(x); //x是左值 template<typename T>
class Test{
Test(Test&& rhs); //已定义特定的类型,&&是一个右值引用
}; template<typename T>
void f(std::vector<T>&& param); //&&右值引用类型,因为在调用这个函数之前,vector<T>中的推断类型已经确定了,到调用f的时候没有类型推断 template<typename T>
void f(const T&& param); //右值引用类型,universal references仅仅在T&&下发生,任何附加条件都会使之失效

  引用折叠:由于存在T&&这种类型,当它作为参数的时候,可能被一个左值引用或右值引用的参数初始化,这时经过类型推导的T&&类型,相比右值引用会发生类型的变化

折叠规则:

  1. 所有的右值引用叠加到右值引用上仍然还是一个右值引用(A&& && 变成 A&&)
  2. 所有的其他引用类型之间的叠加都将变成左值引用(A& & 变成 A&; A& && 变成 A&; A&& & 变成 A&)

  通过typeid(t).name()可以获取到数据类型,但在不同的编译器下,可能不完整;

//msvc
std::cout << typeid(T).name() << std::endl; //gunc 通过__cxa_demangle将低级符号名解码(demangle)成用户级名字 头文件 #include <cxxabi.h>
char *real_name = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, nullptr);
std::cout << real_name;
free(real_name);

std::move

  move实际上并不能移动任何东西,它唯一的功能是将一个左值强制转换为一个右值引用,方便实现移动构造。

std::forward 和 完美转发

  完美转发是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。

template<class T>
void Print(T & t)
{
std::cout << "lvalue : " << t << std::endl;
} template<class T>
void Print(T &&t)
{
std::cout << "rvalue : " << t << std::endl;
} template<class T>
void TestForward(T&& t)
{
Print(t);
Print(std::forward<T>(t));
Print(std::move(t));
} void test()
{
TestForward(1);
int x = 1;
TestForward(x);
TestForward(std::forward<int>(x));
}

万能函数包装器

template <class Function, class... Args>
inline auto FuncWrapper(Function &&f, Args &&... args) -> decltype(f(std::forward<Args>(args)...))
{
return f(std::forward<Args>(args)...);
}

emplace_back 减少内存拷贝和移动

  emplace_back能就地通过参数构造对象,不需要拷贝或移动内存。

unordered container 无序容器

  C++11增加了无需容器unordered_map/unordered_multimap 和 unordered_set/unordered_multiset;由于这些容器中元素不是有序的,比map/multimap和set/multiset效率更高。map和set内部是红黑树,在插入元素时会自动排序,而无序容器内部是散列表(Hash Table),通过哈系,而不是排序来快速操作元素,使得效率更高

struct Key
{
std::string first;
std::string second;
}; struct KeyHash
{
std::size_t operator()(const Key& key)const
{
return std::hash<std::string>()(key.first) ^ (std::hash<std::string>()(key.second) << 1);
}
}; struct KeyEqual
{
bool operator()(const Key &lhs, const Key &rhs) const
{
return lhs.first == rhs.first && lhs.second == rhs.second;
}
}; std::unordered_map<Key,std::string,KeyHash,KeyEqual> munordermap = {
{{"first","first"},"1"},
{{"second","second"},"2"}
};

最新文章

  1. c#获取时间
  2. wamp下多域名配置问题
  3. Windows Store App 图像
  4. 快速上手RaphaelJS--Instant RaphaelJS Starter翻译(二)
  5. 特殊的ASCII码对应的字符
  6. 简单代码在ABAP中实现声音的播放
  7. Chrome 控制台 console
  8. C# 汉字转拼音
  9. Microsoft Office Excel 不能访问文件“XXXXXXXXXXXXX.xls”。 可能的原因有:
  10. 重读gets()与is函数的用法
  11. 译文:Javascript-function&#39;s return
  12. Linux控制台下的快捷键
  13. paip.c++ qt 图片处理 检测损坏的图片
  14. C#整理7——函数
  15. Android Gradle Plugin指南(六)——高级构建定制
  16. MySQL之查询优化方式(笔记)
  17. jQuery之事件移除
  18. day_1 练习2
  19. DNS入门
  20. angular反向代理配置

热门文章

  1. php7连接mysql8
  2. 浅谈 HTTP中Get与Post的区别
  3. 奇思妙想-java实现另类的pipeline模式
  4. ECCV 2018 目标检测 | IoU-Net:将IoU的作用发挥到极致
  5. JS事件冒泡及阻止
  6. tcp\udp 操作系统发展史
  7. 改变Dataframe的列的数据类型
  8. 《JavaScript 模式》读书笔记(5)— 对象创建模式1
  9. 如何设置mysql远程访问
  10. imread()用法|| root权限