C++ 如何启用C++;17英寸

C++ 如何启用C++;17英寸,c++,visual-studio,cmake,c++17,C++,Visual Studio,Cmake,C++17,我使用的是支持集成CMake 3.8的VS15.3。如何在不为每个特定编译器编写标志的情况下以C++17为目标?我当前的全局设置不起作用: # https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # expected behaviour

我使用的是支持集成CMake 3.8的VS15.3。如何在不为每个特定编译器编写标志的情况下以C++17为目标?我当前的全局设置不起作用:

# https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# expected behaviour
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++lastest")
我希望CMake在生成VS解决方案文件时添加“/std:c++lastest”或等效项,但未找到c++17标志,导致编译器错误:

C1189 #error: class template optional is only available with C++17.

您可以为其他编译器(如Clang和GCC)保留
设置(CMAKE_CXX_STANDARD 17)
。但是对于VisualStudio来说,它是无用的

如果CMake仍然不支持此操作,则可以执行以下操作:

if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
endif(MSVC)

您的方法是正确的,但在CMake 3.10之前的版本上,它不适用于MSVC

从:

对于没有标准级别概念的编译器,如MSVC,这没有任何效果

简而言之,CMake尚未更新以适应添加到VC++2017的标准标志

您必须检测是否使用了VC++2017(或更高版本),并自己添加相应的标志



在CMake 3.10(及更高版本)中,这一问题已在较新版本的VC++中得到修复。请参阅。

在现代CMake中,我发现最好在目标级别而不是全局变量级别分配CXX标准,并使用内置属性(见此处:)使其不受编译器的影响

例如:

set_target_properties(FooTarget PROPERTIES
            CXX_STANDARD 17
            CXX_EXTENSIONS OFF
            etc..
            )

现代CMake为此提出了一个接口
目标\u编译\u功能
。 文件如下:

像这样使用它:


target\u compile\u功能(${target\u NAME}私有cxx\u std\u 17)

您还可以使用
target\u compile\u选项
为Visual Studio 2019设置
/std:c++最新版本
标志

if (MSVC_VERSION GREATER_EQUAL "1900")
    include(CheckCXXCompilerFlag)
    CHECK_CXX_COMPILER_FLAG("/std:c++latest" _cpp_latest_flag_supported)
    if (_cpp_latest_flag_supported)
        target_compile_options(${TARGET_NAME} PRIVATE "/std:c++latest")
    endif()
endif()

${TARGET\u NAME}
替换为实际的目标名称。

使用
vs2019

set(CMAKE_CXX_STANDARD 17)

基于我的测试,下面的代码将使VS2019选择/STD:C++最新,否则对于其他平台,它将把C++版本设置为C++ 17。我已经用emscripten、raspian和windows对此进行了测试

if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest")
else(MSVC)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
endif(MSVC)

CMake通常不会消除为每个特定编译器编写标志的需要。使用“VS15.3”是指Visual Studio 2017 preview 3吗?或者你是说Visual Studio 2015 update 3(如果有的话,它不太支持C++17)?@Someprogrammerdude我正在使用
std::optional
功能,如果我将
“/std:C++lastest”
标记手动添加到CmakeList,可以使用这些功能。你需要将标记传递给编译器。编译器接受C++17,而不是
cmake
它是最新的,而不是最新的,允许使用
/std:C++14
/std:C++17
/std:C++latest
标志设置标准。在我的例子中,情况正好相反。我使用的是CMake 3.19.1、VS2019和gcc 7.5.0<代码>设置(CMAKE\U CXX\U标准17)对于VS2019已经足够了,但是gcc需要
目标编译功能(${target\u NAME}私有CXX\u std\u 17)
。即使是一个明确的
add\u compile\u选项(“-std=gnu++17”)
也是不够的。较新的CMake 3.10(及更高版本)文档称它适用于Visual Studio 2015 update 3或更高版本。仅不支持2015 Update 3之前的Visual Studio版本。上面的链接实际上指向最新的文档,它反映了这一点。@Marcus10110正确,将链接更改为指向3.9文档。并添加了关于更新版本的修复说明。谢谢。一个(也许)迂腐的评论:为了使MSVC成为一个合格的编译器,您还必须使用
/Zc:\uuuucplusplus
标志,因为否则
\uucplusplus
宏没有设置为正确的值。一个肯定的迂腐评论是,我认为这是CMAGE中的一个错误:当我请求C++ 11、C++ 14、C++ 17时,我希望CGET设置所有使编译器符合的标记,并且包含了<代码>的值,即,CPLUS PLUS 宏。“现代”CMake到底意味着什么?似乎每个CMake功能都会立即过时,互联网上充斥着过时的问题和答案。“现代CMake”在克雷格·斯科特的书中有描述。在这一过程中,出现了一些重新思考,这导致脚本更加关注抽象目标,而不是强加编译器标志等。请查看他的书:@vitaut您能解释一下为什么将${PROJECT_NAME}重命名为${TARGET_NAME}吗?PROJECT在CMake中有不同的含义:<代码>目标\编译\功能适用于目标。为了清晰起见,我对其进行了更改。请随时回复。我希望接受的答案会随着新语言功能的出现而自动更改。。。这是正确的答案。以上这些都是非常过时的。在CMake中,
PUBLIC
(对每个人来说)=
接口
(对其他人来说)+
PRIVATE
(对我来说),而这段代码可能会回答这个问题,提供关于如何和/或为什么解决这个问题的额外上下文将提高答案的长期价值。这与gcc和clang一起工作。