C++11/17/20 三波更新让 C++ 的书写体验追平甚至部分超越 Java:lambda、auto、范围 for 这些你在 Java 里熟悉的(var、增强 for、lambda)全有了 C++ 版;std::optional、std::variant 更是解决 Java 社区还在用库模拟的问题。
判题沙箱的现代代码里这些特性随处可见:解析提交记录用 optional 表达「这行可能解析失败」,评测结果用 variant 表达「AC / WA / TLE 三选一」,遍历统计用范围 for + 结构化绑定。本课之后,你写的 C++ 就不再是「带类的 C」,而是现代 C++。
先建立图像
同一件事的旧写法 vs 新写法:
旧:for (std::vector<Submission>::iterator it = v.begin(); it != v.end(); ++it)
新:for (const auto& s : v) ← 范围 for + auto
旧:int idx = find(subs, "li"); if (idx == -1) ... ← -1 既是数据又是信号,埋雷
新:auto r = find(subs, "li"); if (r.has_value()) ... ← optional 把「没有」说在类型里
旧:结果码 int verdict,0/1/2/3 全靠注释记
新:std::variant<AC, WA, TLE> result ← 类型系统替你记住所有可能
跟着做
步骤 1:auto——让编译器替你写类型
新建 modern.cpp:
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main() {
auto n = 42; // int
auto d = 3.14; // double
auto s = std::string("AC"); // std::string(auto s = "AC" 推导出 const char*,要小心!)
std::vector<int> scores{60, 87, 95};
auto it = scores.begin(); // std::vector<int>::iterator——没有 auto 就得写全这一长串
std::cout << *it << "\n";
// 整数默认推导成 int;要 64 位就写 auto n = 42LL
return 0;
}
auto 对应 Java 10 的 var,但 C++ 的 auto 能用在更多位置(返回类型、lambda 参数、模板),且没有装箱陷阱——它是纯编译期推导,运行期零差异。
步骤 2:范围 for + 结构化绑定
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main() {
std::vector<std::string> users{"zhang", "li", "wang"};
for (const auto& u : users) { // 值拷贝用 auto u;只读用 const auto&(首选)
std::cout << u << "\n";
}
std::map<std::string, int> costs{{"zhang", 120}, {"li", 45}};
// C++17 结构化绑定:把 pair 拆成两个命名变量
for (const auto& [user, cost] : costs) {
std::cout << user << " 耗时 " << cost << "ms\n";
}
return 0;
}
结构化绑定对 std::pair、std::tuple、struct(按成员顺序)都能拆,Java 的 record 解构(Java 21 模式匹配)对应的就是这个。
步骤 3:lambda——匿名函数
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<int> costs{120, 45, 200, 88};
int limit = 100; // 捕获外部变量
auto count = std::count_if(costs.begin(), costs.end(),
[limit](int c) { return c > limit; }); // [limit]:按值拷贝
std::cout << "超时个数 " << count << "\n";
int total = 0;
std::for_each(costs.begin(), costs.end(),
[&total](int c) { total += c; }); // [&total]:按引用,能修改外部
std::cout << "总耗时 " << total << "\n";
// lambda 本质是编译器生成的匿名类对象(重载了 operator()),对应 Java 的函数式接口实例
auto square = [](int x) { return x * x; };
std::cout << square(9) << "\n";
return 0;
}