Таинственная ошибка, связанная с шаблоном в GCC 7 - PullRequest
0 голосов
/ 04 июля 2019

Я пытаюсь скомпилировать следующий код на gcc 7, но безуспешно:

https://wandbox.org/permlink/IGbLOSnbXChNRvIc

#include <iostream>
#include <cstdlib>

template <auto v, typename T>
struct case_t {
    static constexpr auto value = v;
    using type = T;
    using value_type = decltype(v);
};

template <bool b, typename T>
using cond_t = case_t<b, T>;

namespace internal {
template <typename Cond, typename... Rest>
struct select_impl
    : std::enable_if_t<
          std::is_same_v<typename Cond::value_type, bool>,
          std::conditional_t<Cond::value, Cond, select_impl<Rest...>>> {};

template <typename T>
struct select_impl<T> {
    using type = T; // else clause
};

template <bool b, typename T>
struct select_impl<cond_t<b, T>> {
    // last cond, enforce true
    static_assert(b, "ALL OF THE CASES ARE FALSE BUT NO DEFAULT IS GIVEN");
    using type = T;
};

template <auto v, typename T>
struct case_to_cond {
    using type = T;
};
template <auto v, auto vt, typename T>
struct case_to_cond<v, case_t<vt, T>> {
    using type = cond_t<v == vt, T>;
};

template <auto v, typename T>
using case_to_cond_t = typename case_to_cond<v, T>::type;

} // namespace internal

template <typename Case, typename... Rest>
using select_t = typename internal::select_impl<Case, Rest...>::type;

template <auto v, typename Case, typename... Rest>
using switch_t = select_t<internal::case_to_cond_t<v, Case>,
                          internal::case_to_cond_t<v, Rest>...>;

enum class E {
a, b, c
};
struct A {
    inline static auto name = "this is a";
};
struct B {
    inline static auto name = "this is b";
};
struct C {
    inline static auto name = "this is c";
};

template<auto v>
using  T  = switch_t<v, case_t<E::a, A>, case_t<E::b, B>, case_t<E::c, C>>;

int main()
{
    std::cout << T<E::a>::name << std::endl;
    std::cout << T<E::b>::name << std::endl;
    std::cout << T<E::c>::name << std::endl;
}

По сути, этот код позволяет мне выполнять статическое переключение типов, чтобы избежать вложенных std::conditional. Это хорошо компилируется с clang7 или gcc8, но я не смог найти, где это не так под gcc7.

Любая помощь приветствуется!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...