引言
C++是一门追求极致性能的语言,它的核心哲学是对资源的精确控制,同时保持零开销抽象。本文将从push_back和emplace_back的区别出发,深入探讨左值、右值的本质,以及C++为什么提供这么多精细的控制选项。
一、从问题开始
- std::vector people;Person bob("bob", 22);people.push_back(bob); // 左值people.push_back(Person("alice", 25)); // 右值people.emplace_back("charlie", 30); // 直接构造
复制代码 为什么需要这么多插入方式?它们之间有什么区别?
二、值类别:左值与右值的本质
2.1 什么是左值?什么是右值?
在C++中,每个表达式都有两个属性:
- 类型(如int、Person、std::string)
- 值类别(左值、右值等)
- Person bob("bob", 22); // bob是左值(有名称)Person("alice", 25); // 临时对象是右值(无名称)42 // 字面量是右值
复制代码 2.2 如何判断左值/右值?
左值(lvalue)的判断标准:
- 有名称的变量:bob、x、name
- 可以取地址的:&bob
- 字符串字面量:"hello"(特殊,是左值)
- 返回左值引用的函数调用
右值(rvalue)的判断标准:
- 临时对象:Person("alice", 25)
- 字面量(除字符串外):42、true
- 算术表达式:a + b
- std::move的结果
- Lambda表达式
[code]templatevoid check_value_category(T&& param) { if constexpr (std::is_lvalue_reference_v) { std::cout |