??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&&类型,相比右值引用会发生类型的变化
折叠规则:
??通过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);
??move实际上并不能移动任何东西,它唯一的功能是将一个左值强制转换为一个右值引用,方便实现移动构造。
??完美转发是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。
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能就地通过参数构造对象,不需要拷贝或移动内存。
??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"}
};
原文:https://www.cnblogs.com/s3320/p/12133789.html