繁体   English   中英

C++ 如何通过其索引替换可变参数模板中的类型

[英]C++ how to replace type in variadic template by its index

如何通过索引替换可变参数模板中的 1 种类型? 例如我有:

//-------------static_list-------------
template<class ...Elements>
struct static_list {};

struct execute_command<index, static_list<Commands...>> {
    static constexpr int value = execute_s<index + 1, static_list<Commands...>>::value;
}

我想重写它,所以在命令中它会用类型variable<0, 0>替换例如索引 5 的类型,如下所示:

struct execute_command<false, true, false, false, false, index, static_list<Commands...>> {
    static constexpr int value = execute_s<index + 1, static_list_replace<5, variable<0, 0>, Commands...>>::value;
}

我已经尝试了很多不同的方法,但没有任何效果。 例如:

//-------------static_list_replace-------------
template<std::size_t N, typename T, typename Tuple, class IndexSequence>
struct static_list_replace;

template<std::size_t N, typename T, typename Tuple, std::size_t... Idx>
struct static_list_replace<N, T, Tuple, std::index_sequence<Idx ...>> {
    using type = std::tuple<std::conditional_t<N == Idx, T, std::tuple_element_t<N, Tuple>>...>;
};

或者

namespace detail {
    template<std::size_t N, typename T, typename Tuple, std::size_t... Idx>
    auto replace(std::index_sequence<Idx...>) ->
        std::tuple<std::conditional_t<N == Idx,
        T,
        std::tuple_element_t<N, Tuple>>...>;
}

template <std::size_t N, typename T, typename... Args>
using Replace = decltype(detail::replace<N, T, std::tuple<Args...>>
    (std::index_sequence_for<Args...>{}));

或者我尝试获取列表的开头并在没有一个元素的情况下结束,然后将其打包为static_list<list_beginning<index, Commands...>, element, list_ending<index, Commands...>>>

没有任何效果。

我想有很多方法...

例如,给定一个助手 class 作为slrh (静态列表替换助手)

template <std::size_t, typename...>
struct slrh;

template <std::size_t N, typename R, std::size_t ... Is, typename ... Ts>
struct slrh<N, R, std::index_sequence<Is...>, Ts...>
 { using type = static_list<std::conditional_t<(N == Is), R, Ts>...>; };

您的static_list_replace可以简单地写成如下

template <std::size_t, typename R, typename SL>
struct static_list_replace;

template <std::size_t N, typename R, typename ... Ts>
struct static_list_replace<N, R, static_list<Ts...>>
   : public slrh<N, R, std::make_index_sequence<sizeof...(Ts)>, Ts...>
 { };

下面是一个完整的编译示例

#include <utility>
#include <type_traits>

template <typename ...>
struct static_list
 { };

template <std::size_t, typename...>
struct slrh;

template <std::size_t N, typename R, std::size_t ... Is, typename ... Ts>
struct slrh<N, R, std::index_sequence<Is...>, Ts...>
 { using type = static_list<std::conditional_t<(N == Is), R, Ts>...>; };

template <std::size_t, typename R, typename SL>
struct static_list_replace;

template <std::size_t N, typename R, typename ... Ts>
struct static_list_replace<N, R, static_list<Ts...>>
   : public slrh<N, R, std::make_index_sequence<sizeof...(Ts)>, Ts...>
 { };

template <int...>
struct variable
 { };

int main()
 {
   using T1 = static_list<char, short, int, long, long long>;
   using T2 = static_list<char, short, char, long, long long>;
   using T3 = typename static_list_replace<2u, char, T1>::type;

   using T4 = static_list_replace<4, variable<16, 16>,
                static_list<char, short, int, long, long long>>::type;
   using T5 = static_list<char, short, int, long, variable<16, 16>>;

   static_assert( std::is_same_v<T2, T3> );
   static_assert( std::is_same_v<T4, T5> );
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM