conan 通过 cmaketoolchain 将 compiler.cppstd 设置转为 cmake_cxx_standard 等变量,但需在 conan install 时显式指定 -s compiler.cppstd=17,且 cmakelists.txt 中仍须在 project() 后 set(cmake_cxx_standard) 以确保生效。

Conan 本身不直接设置 C++ 标准,但能影响 CMake 的标准行为
Conan 不会自动修改 CMAKE_CXX_STANDARD 或往编译命令里硬塞 -std=...。它真正起作用的方式是:通过 CMakeToolchain 生成器,把你在 Conan profile 或 conan install 命令中声明的 compiler.cppstd 设置,翻译成 CMake 工具链文件里的 CMAKE_CXX_STANDARD 和 CMAKE_CXX_EXTENSIONS 等变量。
换句话说:你告诉 Conan “我要用 C++17”,Conan 就让 CMake 知道这件事——但最终是否生效、是否被 target 继承,还得看 CMakeLists.txt 里怎么写。
必须在 conan install 时显式传入 compiler.cppstd
如果你没在安装依赖时指定 C++ 标准,CMakeToolchain 默认可能沿用 profile 里的值(通常是 c++14 或更老),而不会读取 CMakeLists.txt 里的 set(CMAKE_CXX_STANDARD 17)。
- 正确做法:运行
conan install . --build=missing -s compiler.cppstd=17 -if build - 错误做法:只运行
conan install . -if build,然后指望 CMakeLists.txt 里的set(CMAKE_CXX_STANDARD 17)能“覆盖”工具链 -
compiler.cppstd是 Conan settings 的一部分,不是选项(options),不能写在conanfile.txt的[options]段里 - 若用自定义 profile(如
mygcc),需确保 profile 文件里有compiler.cppstd=17这一行
CMakeLists.txt 中 set(CMAKE_CXX_STANDARD ...) 仍需保留
Conan 生成的 conan_toolchain.cmake 会设置 CMAKE_CXX_STANDARD,但它通常出现在 include() 之后;而 CMake 要求 set(CMAKE_CXX_STANDARD ...) 必须在 project() 之后、任何 add_executable() 之前 —— 否则部分 target 可能不继承该标准。
- 推荐顺序:
project()→include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake)→set(CMAKE_CXX_STANDARD 17)→set(CMAKE_CXX_STANDARD_REQUIRED ON)→set(CMAKE_CXX_EXTENSIONS OFF)→ 定义 targets - 如果只依赖 Conan 工具链而不显式 set,某些旧版 CMake(CMAKE_CXX_STANDARD 保持默认的
98 - 多个 target 需不同标准时,
set_property(TARGET xxx PROPERTY CXX_STANDARD 20)优先级高于全局CMAKE_CXX_STANDARD,且不受 Conan 工具链干扰
常见错误:CMakeToolchain 和 CMakeLists.txt 标准冲突
现象:编译报错说 constexpr if 不支持,或 std::optional 找不到,但你明明写了 set(CMAKE_CXX_STANDARD 17)。
- 检查
conan_toolchain.cmake是否真包含set(CMAKE_CXX_STANDARD "17")(打开build/generators/conan_toolchain.cmake查看) - 确认
conan install命令带了-s compiler.cppstd=17;否则工具链可能写的是"14"甚至空字符串 - 注意 CMake 缓存:改了
conan install参数后,必须删掉build/目录或运行conan install重新生成工具链,否则旧缓存会继续用错的标准 - MSVC 用户注意:
compiler.cppstd=17在 Conan 中对 MSVC 实际影响有限,因为 MSVC 不用-std=标志;它更依赖/std:c++17,而这由工具链根据compiler.version自动推导,不一定和cppstd完全对齐
最易被忽略的一点:Conan 的 compiler.cppstd 是给工具链“提需求”,CMake 的 CMAKE_CXX_STANDARD 是给 target“下指令”,两者要对上号,中间不能断档——尤其在 CI 或多构建目录场景下,漏传 -s compiler.cppstd 或忘了清理旧 build 目录,问题就会静默出现。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











