Open v4if opened 7 years ago
概括的讲,凡是能够取地址的可以称之为左值,反之称之为右值,C++中并没有对左值和右值给出明确的定义,从其解决手段来看类似上面的定义,当然我们还可以定义为:有名字的对象为左值,没有名字的对象为右值。
std::move可以将一个左值转化为右值引用触发移动语义
template<typename T>
decltype(auto) move(T&& param)
{
using ReturnType = remove_reference_t<T>&&;
return static_cast<ReturnType>(param);
}
// 触发move语义,src被掏空了
string(std::string&& src)
{
data = src.data;
src.data = nullptr;
}
通常用于转移对象的所有权
右值通常都是临时的,所以可以随意修改;如果知道某个参数的右值,就可以将其看作为一个临时存储或窃取
内容,也不影响程序的正确性
例如指针的转移是通过移动,而非拷贝
/*
虽然右值引用参数绑定了右值,不过在函数内部,会当做左值来处理
**/
void do_stuff(X&& x_) {
X a(x_); // 拷贝
X b(std::move(x_)); // 移动
}
追踪返回类型
template<typename T1, typename T2>
auto sum(T1& t1, T2& t2) -> decltype(t1 + t2) {
return t1 + t2;
}
auto占位符和->return_type是构成追踪返回类型函数的两个基本元素,追踪返回类型的函数和普通函数的声明最大区别在于返回类型的后置
有缺陷的枚举类型,具名的enum类型的名字,以及enum成员的名字都是全局可见的,因此枚举类型会污染全局变量 为了解决这一问题,可以对枚举类型进行封装
class Type{
public:
enum type{general, light, medium, heavy};
};
强枚举类型
enum class Type{general, light, medium, heavy};
// 强作用域
Type::light;
unique_ptr与所指对象的内存绑定紧密,不能与其他unique_ptr类型的指针对象共享所指对象的内存,只能够通过move进行所有权的转移
shared_ptr允许过个该智能指针共享的拥有
同一堆分配对象的内存,在实现上采用了引用计数
weak_ptr可以指向shared_ptr指针指向的对象内存,却不拥有该内存。而使用weak_ptr成员lock,则可返回其指向内存的一个shared_ptr对象,且在所指向对象内存无效时,返回指针空值(nullptr),因此可以验证shared_ptr智能指针的有效性
void check(weak_ptr<int>& wp) {
shared_ptr<int> sp = wp.lock();
if (sp != nullptr)
cout << "still " << *sp << endl;
else
cout << "pointer is invalid." << endl;
}
lambda对于按值方式传递的捕捉列表,其传递的值在lambda函数定义的时候就已经决定了。而按引用传递的捕捉列表变量,其传递的值等于lambda函数调用时的值。
int j = 12;
auto by_val_lambda = [=] {return j + 1;}
auto by_ref_lambda = [&] {return j + 1;}
std::cout << "by_val_lambda: " << by_val_lambda() << std::endl;
std::cout << "by_ref_lambda: " << by_ref_lambda() << std::endl;
j++;
std::cout << "by_val_lambda: " << by_val_lambda() << std::endl;
std::cout << "by_ref_lambda: " << by_ref_lambda() << std::endl;
/*
by_val_lambda: 13
by_ref_lambda: 13
by_val_lambda: 13
by_ref_lambda: 14
*/
C++11
Rvalue Reference