Следующий код прекрасно компилируется с последней версией Visual Studio Comumnity 16.5.4, настроенной на использование последней версии стандарта C ++, однако не удается скомпилировать на G ++ 9.2 с очень криптительным c и бесполезным сообщением об ошибке.
#include <iostream>
#include <utility>
namespace Aux {
template <std::size_t INDEX, typename TYPE>
struct TypeValue {
static TYPE get(std::in_place_index_t<INDEX>);
};
template <std::size_t INDEX, typename... TYPES>
struct TGetType;
template <std::size_t INDEX, std::size_t... INDICES, typename... TYPES>
struct TGetType<INDEX, std::index_sequence<INDICES...>, TYPES...>
: TypeValue<INDICES, TYPES>... {
using TypeValue<INDICES, TYPES>::get...;
using Type = decltype(get(std::in_place_index_t<INDEX>()));
};
}
template <std::size_t INDEX, typename... TYPES>
struct TGetType {
static_assert(INDEX < sizeof...(TYPES));
using Type = typename Aux::TGetType<INDEX, std::index_sequence_for<TYPES...>, TYPES...>::Type;
};
template <std::size_t INDEX, typename... TYPES>
using GetType = typename TGetType<INDEX, TYPES...>::Type;
template <std::size_t INDEX, typename... TYPES>
inline constexpr auto get_type = GetType<INDEX, TYPES...>();
int
main() {
using T = GetType<1, int, double, bool>;
}
Вот сообщение об ошибке:
C:\Users\joaom\Dropbox\++A\tests\gcc-err.cpp: In instantiation of 'struct Aux::TGetType<1, std::integer_sequence<long long unsigned int, 0, 1, 2>, int, double, bool>':
C:\Users\joaom\Dropbox\++A\tests\gcc-err.cpp:24:8: required from 'struct TGetType<1, int, double, bool>'
C:\Users\joaom\Dropbox\++A\tests\gcc-err.cpp:28:7: required by substitution of 'template<long long unsigned int INDEX, class ... TYPES> using GetType = typename TGetType::Type [with long long unsigned int INDEX = 1; TYPES = {int, double, bool}]'
C:\Users\joaom\Dropbox\++A\tests\gcc-err.cpp:35:40: required from here
C:\Users\joaom\Dropbox\++A\tests\gcc-err.cpp:17:28: error: cannot convert 'in_place_index_t<1>' to 'in_place_index_t<2>'
17 | using Type = decltype(get(std::in_place_index_t<INDEX>()));
| ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\joaom\Dropbox\++A\tests\gcc-err.cpp:7:19: note: initializing argument 1 of 'static TYPE Aux::TypeValue<INDEX, TYPE>::get(std::in_place_index_t<_Idx>) [with long long unsigned int INDEX = 2; TYPE = bool]'
7 | static TYPE get(std::in_place_index_t<INDEX>);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
[Finished in 0.4s]
Я установил G ++ через https://nuwen.net/mingw.html, и он пришел со следующей конфигурацией:
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=c:/program\ files/mingw-w64/mingw-17.1-without-git/bin/../libexec/gcc/x86_64-w64-mingw32/9.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../src/configure --enable-languages=c,c++ --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --disable-multilib --prefix=/c/temp/gcc/dest --with-sysroot=/c/temp/gcc/dest --disable-libstdcxx-pch --disable-libstdcxx-verbose --disable-nls --disable-shared --disable-win32-registry --with-tune=haswell --enable-threads=posix --enable-libgomp
Thread model: posix
gcc version 9.2.0 (GCC)
Еще не пробовал с Clang, так как последняя версия библиотек Visual Studio C ++ еще не совместима с Clang:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\concepts:16:2: error: Despite the presence of some Clang-related bits, this header currently does not support Clang. You can define _SILENCE_CLANG_CONCEPTS_MESSAGE to silence this message and acknowledge that this is unsupported.
#error Despite the presence of some Clang-related bits, this header currently does not support Clang. \
Соответствует ли мой код стандарту или я полагаюсь на MS C расширенное поведение? Я действительно не вижу в этом ничего странного или неправильного, и более сложные случаи метапрограммирования, подобные этому, кажутся хорошо работающими в Visual Studio.