【问题标题】:C++ how to replace type in variadic template by its indexC ++如何通过其索引替换可变参数模板中的类型
【发布时间】:2021-05-04 17:38:22
【问题描述】:

如何通过索引替换可变参数模板中的 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;
}

我想重写它,所以在命令中它会将例如索引 5 处的类型替换为 variable&lt;0, 0&gt; 类型,如下所示:

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&lt;list_beginning&lt;index, Commands...&gt;, element, list_ending&lt;index, Commands...&gt;&gt;&gt; 一样打包它

没有任何效果。

【问题讨论】:

    标签: c++ templates variadic-templates template-meta-programming


    【解决方案1】:

    我想有很多方法......

    例如,给定一个助手类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> );
     }
    

    【讨论】:

    • 当我这样写时:template &lt;int index, typename ...Commands&gt; struct execute_command&lt;false, true, false, false, false, index, static_list&lt;Commands...&gt;&gt; { static constexpr int value = execute_s&lt;index + 1, static_list_replace&lt;4, variable&lt;16, 16&gt;, static_list&lt;Commands...&gt;&gt;::type&gt;::value; }; 它给了我一个错误:slrh::type : 非法使用这种类型作为表达式。我在所有其他实现中都遇到了这个错误,这是什么意思?
    • @Rikib161999 - 我已将完整示例与variable&lt;16, 16&gt; 替换集成。有用。抱歉,但没有完整(非)编译示例,我无法想象您的问题出在哪里。
    • 我不知道为什么使用类型对我来说不起作用,所以我只是用 int 值做了它并循环它,现在它正在工作非常感谢您的帮助!欣赏!
    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 2015-02-19
    • 2011-07-11
    • 2016-10-10
    相关资源
    最近更新 更多