Visual Studio 2019 拒绝“bool 概念”,而 gcc 8 不编译没有“bool”的概念
Visual Studio 2019 rejects `bool concept` while gcc 8 doesn't compile concepts without `bool`
我认为 c++ concepts 是编写 c++ 模板代码的更好方法,具有更好的错误消息和更快的编译时间,因此我将 Visual Studio 升级到 2019 并仍在等待 clang 支持 concepts
但是我用 visual studio 2019 的 msvc 和 mingw-w64 的 g++ 8 测试了一些简单的代码,我遇到了一些麻烦。
这是测试:
#include <iostream>
using namespace std;
// this compiles under g++ 8 but not visual studio 2019
template <class T>
bool concept CharT = std::is_same_v<T, char> || std::is_same_v<T, wchar_t> ||
std::is_same_v<T, char16_t> || std::is_same_v<T, char32_t>;
// this compile under visual studio 2019 but not g++
//template <class T>
//concept CharT = std::is_same_v<T, char> || std::is_same_v<T, wchar_t> ||
// std::is_same_v<T, char16_t> || std::is_same_v<T, char32_t>;
template <CharT char_type>
void PrintChar(char_type ch)
{
wcout << ch << endl;
}
int main()
{
PrintChar('c');
PrintChar(L'h');
PrintChar('a');
PrintChar('r');
}
Visual Studio 调用:
cl /std:c++latest concepts.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28316 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.
concepts.cpp
concepts.cpp(7): error C2988: unrecognizable template declaration/definition
concepts.cpp(7): error C2059: syntax error: 'concept'
concepts.cpp(7): fatal error C1903: unable to recover from previous error(s); stopping compilation
Internal Compiler Error in C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.24.28314\bin\HostX64\x64\cl.exe. You will be prompted to send an error report to Microsoft later.
g++ 调用
g++ -std=c++2a -fconcepts concepts.cpp -o c.exe
concepts.cpp:12:9: error: 'CharT' does not name a type; did you mean 'char'?
concept CharT = std::is_same_v<T, char> || std::is_same_v<T, wchar_t> ||
^~~~~
char
concepts.cpp:15:11: error: 'CharT' has not been declared
template <CharT char_type>
^~~~~
concepts.cpp:16:16: error: variable or field 'PrintChar' declared void
void PrintChar(char_type ch)
^~~~~~~~~
concepts.cpp:16:16: error: 'char_type' was not declared in this scope
concepts.cpp:16:16: note: suggested alternative: 'wchar_t'
void PrintChar(char_type ch)
^~~~~~~~~
wchar_t
concepts.cpp: In function 'int main()':
concepts.cpp:23:2: error: 'PrintChar' was not declared in this scope
PrintChar('c');
^~~~~~~~~
应该支持这两种语法吗?或者我在一个编译器上使用已弃用或删除的语法,而另一个编译器不支持它?
带bool
的语法不是C++20的概念,而是之前的Concepts TS(Technical Specification)的语法。后者是对 C++17 的实验性扩展,取代了基于 TS 的 C++20 概念添加,但对语法和语义做了一些更改。
GCC 8 仅支持 TS,不支持 C++20 概念,后者需要 GCC 10。
有关概念(TS 和 C++20)的编译器支持列表,请参阅 this cppreference.com page for documentation of the C++20 concepts additions and this one for the Concepts TS. See also this page。
正如所说,concept bool
是TS语法,而concept
是C++20语法。
如果你真的需要支持两个编译器,你可以使用feature test macro到select正确的语法(尽管从技术上讲Concepts TS' t 列在那 table):
#if __cpp_concepts >= 201707
// working paper, C++20 concepts
#define CONCEPT concept
#else
// TS
#define CONCEPT concept bool
#endif
template <typename T>
CONCEPT C = true;
这适用于所有支持概念的编译器。
我认为 c++ concepts 是编写 c++ 模板代码的更好方法,具有更好的错误消息和更快的编译时间,因此我将 Visual Studio 升级到 2019 并仍在等待 clang 支持 concepts
但是我用 visual studio 2019 的 msvc 和 mingw-w64 的 g++ 8 测试了一些简单的代码,我遇到了一些麻烦。
这是测试:
#include <iostream>
using namespace std;
// this compiles under g++ 8 but not visual studio 2019
template <class T>
bool concept CharT = std::is_same_v<T, char> || std::is_same_v<T, wchar_t> ||
std::is_same_v<T, char16_t> || std::is_same_v<T, char32_t>;
// this compile under visual studio 2019 but not g++
//template <class T>
//concept CharT = std::is_same_v<T, char> || std::is_same_v<T, wchar_t> ||
// std::is_same_v<T, char16_t> || std::is_same_v<T, char32_t>;
template <CharT char_type>
void PrintChar(char_type ch)
{
wcout << ch << endl;
}
int main()
{
PrintChar('c');
PrintChar(L'h');
PrintChar('a');
PrintChar('r');
}
Visual Studio 调用:
cl /std:c++latest concepts.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28316 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.
concepts.cpp
concepts.cpp(7): error C2988: unrecognizable template declaration/definition
concepts.cpp(7): error C2059: syntax error: 'concept'
concepts.cpp(7): fatal error C1903: unable to recover from previous error(s); stopping compilation
Internal Compiler Error in C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.24.28314\bin\HostX64\x64\cl.exe. You will be prompted to send an error report to Microsoft later.
g++ 调用
g++ -std=c++2a -fconcepts concepts.cpp -o c.exe
concepts.cpp:12:9: error: 'CharT' does not name a type; did you mean 'char'?
concept CharT = std::is_same_v<T, char> || std::is_same_v<T, wchar_t> ||
^~~~~
char
concepts.cpp:15:11: error: 'CharT' has not been declared
template <CharT char_type>
^~~~~
concepts.cpp:16:16: error: variable or field 'PrintChar' declared void
void PrintChar(char_type ch)
^~~~~~~~~
concepts.cpp:16:16: error: 'char_type' was not declared in this scope
concepts.cpp:16:16: note: suggested alternative: 'wchar_t'
void PrintChar(char_type ch)
^~~~~~~~~
wchar_t
concepts.cpp: In function 'int main()':
concepts.cpp:23:2: error: 'PrintChar' was not declared in this scope
PrintChar('c');
^~~~~~~~~
应该支持这两种语法吗?或者我在一个编译器上使用已弃用或删除的语法,而另一个编译器不支持它?
带bool
的语法不是C++20的概念,而是之前的Concepts TS(Technical Specification)的语法。后者是对 C++17 的实验性扩展,取代了基于 TS 的 C++20 概念添加,但对语法和语义做了一些更改。
GCC 8 仅支持 TS,不支持 C++20 概念,后者需要 GCC 10。
有关概念(TS 和 C++20)的编译器支持列表,请参阅 this cppreference.com page for documentation of the C++20 concepts additions and this one for the Concepts TS. See also this page。
正如concept bool
是TS语法,而concept
是C++20语法。
如果你真的需要支持两个编译器,你可以使用feature test macro到select正确的语法(尽管从技术上讲Concepts TS' t 列在那 table):
#if __cpp_concepts >= 201707
// working paper, C++20 concepts
#define CONCEPT concept
#else
// TS
#define CONCEPT concept bool
#endif
template <typename T>
CONCEPT C = true;
这适用于所有支持概念的编译器。