GCC 7中与模板有关的神秘错误

时间:2019-07-04 00:42:43

标签: c++ templates gcc generic-programming

我正在尝试在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下出错的地方。

感谢您的帮助!

0 个答案:

没有答案