Прекрасно работает в Visual Studio, не компилируется на G ++ 9.2 - PullRequest
3 голосов
/ 28 апреля 2020

Следующий код прекрасно компилируется с последней версией 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.

...