此代码获取满足测试的第一个元组元素(在本例中,如果它派生 Base
)。 如何 static_assert 认为只有一个满足该条件的元素可能存在?(很像 C++17 的 std::get<class>
如果提供的类型名存在多个元素,则无法编译。)
template<class...>
struct voider { using type = void; };
template<class...Ts>
using void_t = typename voider<Ts...>::type;
template<template<class...> class Test, class Tuple>
struct get_first_pass;
template<template<class...> class Test, class Tuple>
using get_first_pass_t = typename get_first_pass<Test, Tuple>::type;
template<template<class...> class, class, class...>
struct first_pass {};
template<template<class...> class Test, class T0, class...Ts>
struct first_pass<Test, std::enable_if_t<!Test<T0>::value>, T0, Ts...> :
first_pass<Test, void, Ts...>
{};
template<template<class...> class Test, class T0, class...Ts>
struct first_pass<Test, std::enable_if_t<Test<T0>::value>, T0, Ts...> {
using type = T0;
};
template<template<class...> class Test, template<class...> class Tuple, class...Ts>
struct get_first_pass<Test, Tuple<Ts...>> : first_pass<Test, void, Ts...>
{};
template<class Base>
struct is_derived_from {
template<class Derived>
using test = std::is_base_of<std::decay_t<Base>, std::decay_t<Derived>>;
};
template<class Base, class Tuple>
using get_first_derived =
get_first_pass_t<is_derived_from<Base>::template test, Tuple>;
template<class Base, class Tuple>
auto get_from_base(Tuple&& tuple)
-> decltype(std::get< get_first_derived<Base, std::decay_t<Tuple>> >(
std::forward<Tuple>(tuple))) {
return std::get< get_first_derived<Base, std::decay_t<Tuple>> >(
std::forward<Tuple>(tuple));
}
最佳答案
不确定您到底想要什么。
但我想,如果你写一个“计数器”如下
// count is derived from
template <typename, typename>
struct count_idf : public std::integral_constant<std::size_t, 0U>
{ };
template <typename Base, template <typename...> class C, typename ... Ts>
struct count_idf<Base, C<Ts...>>
: public std::integral_constant<std::size_t,
(is_derived_from<Base>::template test<Ts>::value + ...)>
{ };
您可以在get_from_base()
中添加一个static_assert()
,如下所示
template<class Base, class Tuple>
auto get_from_base(Tuple&& tuple)
-> decltype(std::get< get_first_derived<Base, std::decay_t<Tuple>> >(
std::forward<Tuple>(tuple))) {
static_assert( 1U == count_idf<Base, std::decay_t<Tuple>>{},
"not one and only one" );
return std::get< get_first_derived<Base, std::decay_t<Tuple>> >(
std::forward<Tuple>(tuple));
}
关于c++ - 你能 static_assert 一个元组只有一种类型满足特定条件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48993118/