我正在开发 Qt 项目,该项目旨在构建在 Windows 和 Linux 上。作为构建系统,我在Ubuntu 16.04上使用GCC 5.4 CMake ,在Windows 10上使用Visual Studio 2017.因为当前使用的标准是c++14但我想使用便捷类型{{ 3}}我将其定义如下:
#if __cplusplus >= 201703L
#include <type_traits>
#else
namespace std {
template<typename... Ts> struct make_void { typedef void type; };
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
}
#endif
如果我使用上面提到的编译器在Linux下构建项目,上面的定义工作正常,但是当我尝试在Windows下构建它时,我收到以下错误消息:
C2386: 'void_t': a symbol with this name already exists in the current scope
U1077: 'C:\PROGRA~2\MICROS~4\2017\ENTERP~1\VC\Tools\MSVC\1411~1.255\bin\HostX64\x64\cl.exe' : return code '0x2'
U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\nmake.exe"' : return code '0x2'
U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\nmake.exe"' : return code '0x2'
顶级CMake文件设置C ++标准如下:
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
我不明白为什么当标准设置为std::void_t
时,Visual Studio 2017会抱怨std::void_t
。这是一种正常行为,我认为错误地以所示方式污染std
命名空间不会导致错误吗?如何克服Visual Studio 2017产生的这些错误?
修改:我刚刚注意到依赖预定义宏__cplusplus
的值可能会导致c++14。 unexpected results问题也针对__cplusplus
宏。
答案 0 :(得分:4)
这是一种正常的行为,我认为错误地以显示的方式污染std命名空间不会导致错误吗?
标准库拥有namespace std
- 您只能在特定情况下向其添加内容。声明全新的类型不是其中之一,你应该不这样做。污染namespace std
在某些时候会遇到麻烦。
在这种特殊情况下,使用您自己的void_t
而不是标准库版本真的没有什么可失去的。它会工作的。所以就这样做吧。或者,如果您确实想要使用标准名称,请将其中一个或另一个带入不同的名称空间:
namespace xstd {
#if __cplusplus >= 201703L
using std::void_t;
#else
template<typename... Ts> struct make_void { typedef void type; };
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
#endif
}
// use xstd::void_t throughout
答案 1 :(得分:2)
CMAKE_CXX_STANDARD
选项目前对Visual Studio的影响有限。
与提供-std
命令行开关以指定所请求的标准版本的gcc或clang不同,Visual C ++过去常常为您提供所有最新功能。仅在2015版本(更新3)中,他们引入了/std
option,旨在为较新的语言功能提供选择加入机制。
不幸的是,这还不像gcc或clang那样成熟,所以你可能仍然会得到你不会想到的功能。