新工程引入range-v3库报duplicate ‘constexpr’错误的原因与解决
解决range-v3在C++20环境下的"duplicate ‘constexpr’"编译错误
最近我碰到了一个挺折腾的问题:同一个仅头文件的range-v3库,在旧项目里运行完全正常,但在新项目中引入就疯狂报**duplicate ‘constexpr’**编译错误。下面把问题细节和解决过程分享给大家:
项目环境与代码
新项目的基础配置:
- IDE:CLion 2019.3(已启用C++20标准)
- 编译器:GCC 9.2
- 项目结构:包含
cmake_build-debug目录、CMakeLists.txt和main.cpp
触发错误的main.cpp代码
#include <vector> #include <range/v3/view/transform.hpp> // 这一行触发编译错误 int main() { std::vector<int> myvec{1,2,3,4}; return 0; }
旧项目可正常运行的CMake配置
cmake_minimum_required(VERSION 3.15) project(codingchallange C CXX) set(CMAKE_CXX_STANDARD 20) set(SOURCE_FILES main.cpp) add_library(range_v3 INTERFACE IMPORTED) set_target_properties(range_v3 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include) add_executable(codingchallange ${SOURCE_FILES}) target_link_libraries(codingchallange range_v3) // 链接库到可执行文件
编译错误信息
Scanning dependencies of target codingchallange [ 50%] Building CXX object CMakeFiles/codingchallange.dir/main.cpp.o In file included from /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include/range/v3/range_fwd.hpp:22, from /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include/range/v3/view/transform.hpp:23, from /home/myname/CLionProjects/codingchallange/main.cpp:4: /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include/range/v3/range/conversion.hpp:207:19: error: duplicate ‘constexpr’ 207 | constexpr CPP_concept_bool has_allocator_type = | ^~~~~~~~~~~~~ /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include/range/v3/range/conversion.hpp:211:19: error: duplicate ‘constexpr’ 211 | constexpr CPP_concept_bool range_and_not_view = | ^~~~~~~~~~~~~ /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include/range/v3/range/conversion.hpp:223:19: error: duplicate ‘constexpr’ 223 | constexpr CPP_concept_bool convertible_to_cont_impl_ = | ^~~~~~~~~~~~~ /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include/range/v3/view/transform.hpp:74:19: error: duplicate ‘constexpr’ 74 | constexpr CPP_concept_bool iter_transform_1_readable = | ^~~~~~~~~~~~~ /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include/range/v3/view/transform.hpp:93:19: error: duplicate ‘constexpr’ 93 | constexpr CPP_concept_bool iter_transform_2_readable =
问题根源与解决方法
折腾了好一会儿我才反应过来:旧项目的CMake里藏了一个我当时随手加的编译定义,正是它解决了冲突!
问题的核心原因是:GCC 9.x对C20概念的支持属于实验性阶段,而range-v3库本身会自己模拟概念实现;当启用C20标准时,编译器内置的概念支持和range-v3的模拟代码发生了冲突,导致constexpr重复定义。
解决方法很简单,只需要在新项目的CMake配置中添加一个编译定义,告诉range-v3使用编译器原生的C++20概念支持,而非自己的模拟代码:
修改后的完整CMakeLists.txt:
cmake_minimum_required(VERSION 3.15) project(codingchallange C CXX) set(CMAKE_CXX_STANDARD 20) set(SOURCE_FILES main.cpp) add_library(range_v3 INTERFACE IMPORTED) set_target_properties(range_v3 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES /home/myname/CLionProjects/Libraries2/range-v3/range-v3-master/include) add_executable(codingchallange ${SOURCE_FILES}) # 添加这一行解决constexpr重复定义问题 target_compile_definitions(codingchallange PRIVATE RANGES_CXX_CONCEPTS=1) target_link_libraries(codingchallange range_v3)
添加RANGES_CXX_CONCEPTS=1这个定义后,range-v3会自动适配编译器的原生概念支持,冲突瞬间消失,项目可以正常编译运行了。
内容的提问来源于stack exchange,提问作者M.Mac
相关产品推荐
相关产品推荐

