我正在尝试在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下出错的地方。
感谢您的帮助!