加 -std=c++11 是因为 g++ 默认使用 c++98 标准(__cplusplus=199711l),不识别 auto 范围for、nullptr、std::thread 等 c++11 语法和特性;指定后才启用对应解析、库支持及宏定义(__cplusplus=201103l)。

必须加 -std=c++11,否则像 for (auto x : vec)、nullptr、std::thread 这些语法会直接报错 —— 默认模式是 C++98 或更旧,连 auto 推导都不认。
为什么加 -std=c++11 才行
g++ 默认不启用 C++11 特性,哪怕你用的是 GCC 4.8+(最早支持 C++11 的稳定版本)。它只在显式指定标准时才开启对应语法解析和库支持。比如:
-
__cplusplus宏值:不加-std=c++11时是199711L(C++98),加了才是201103L - 标准库头文件行为也会变:比如
<chrono></chrono>在 C++98 模式下可能根本不可用或声明不全 - 某些警告(如使用未初始化的
std::vector::data())只在 C++11+ 下触发
-std=c++11 放哪儿都行,但别放错位置
参数顺序无关紧要,但必须出现在源文件名之前,且不能被其他选项覆盖。常见错误写法:
- ❌
g++ main.cpp -std=c++11 -o app—— 实际上没问题,但容易误以为顺序敏感(其实 OK) - ❌
g++ -o app main.cpp -std=c++11—— 仍然有效,GCC 允许后置 - ✅ 正确姿势:
g++ -std=c++11 -Wall -g main.cpp -o app - ⚠️ 注意:
-std=gnu++11启用 GNU 扩展(比如typeof),而-std=c++11更严格、可移植性更好
编译失败时先看这三行错误信息
遇到报错别急着改代码,先扫一眼终端输出最上面几行:
- 看到
range-based ‘for’ loops are not allowed in C++98 mode→ 肯定漏了-std=c++11 - 看到
‘nullptr’ was not declared in this scope→ 同样是标准没开 - 看到
error: ‘to_string’ is not a member of ‘std’→ 可能是 GCC 版本太低(to_string 是 C++11 引入的 - 如果用了
std::make_unique却报错 → 那得换-std=c++14,它不在 C++11 里
真正容易被忽略的是:跨平台项目中,不同机器的 GCC 版本差异很大。CentOS 7 自带 GCC 4.8.5,刚好够用;但 Ubuntu 16.04 默认是 5.4,而 Alpine Linux 常用的 musl 工具链可能连 -std=c++11 都不完全支持 —— 这时候光加参数没用,得先确认编译器能力边界。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











