【问题标题】:Rewriting a parameter pack by replacing types通过替换类型重写参数包
【发布时间】:2018-04-25 11:59:23
【问题描述】:

在这里,我想重写一个可变参数模板参数包并将某些类型的出现替换为另一种类型。这是一个类似伪代码的示例:

#include <string>

template <typename Params,  typename Args>
struct TermRewrite {

    template <typename... Body>
    static auto constexpr eval(){
        // Fill here...
    }
};

int main() {
    TermRewrite<int, char>::eval<int, std::string, double>(); 
    // should give me pack of types as <char, std::string, double>
    // ie. it should replace type int with char in Body...

}

这样我就可以将这些术语重写链接到最后。基本上,我想在转发之前转换可变参数模板。我怎样才能做到这一点?我无法提出解决方案。对于所有你想知道的,这是我自己编造的练习。另外,您对可用性有什么建议,以便更轻松地链接TermRewrite 调用?

【问题讨论】:

    标签: c++ variadic-templates


    【解决方案1】:

    您使用带有单个参数的元函数的参数包扩展

    template<typename From, typename To>
    struct replace
    {
        template<typename T>
        using replace_fn = std::conditional_t<std::is_same_v<From, T>, To, T>;
    
        template<typename... Args>
        using apply = std::tuple<replace_fn<Args>...>;
    };
    

    请注意,您必须将结果另存为带有参数包的模板,例如 std::tuple

    如果你想链接替换,你可以写

    template<typename From, typename To, typename... Args>
    struct replace_impl
    {
        template<typename T>
        using replace_fn = std::conditional_t<std::is_same_v<From, T>, To, T>;
        using type = std::tuple<replace_fn<Args>...>;
    };
    
    template<typename From, typename To, typename... Args>
    struct replace_impl<From, To, std::tuple<Args...>>
    {
        template<typename T>
        using replace_fn = std::conditional_t<std::is_same_v<From, T>, To, T>;
        using type = std::tuple<replace_fn<Args>...>;
    };
    
    template<typename From, typename To>
    struct replace
    {
        template<typename... Args>
        using apply = typename replace_impl<From, To, Args...>::type;
    };
    

    并用作

    replace<char, float>::apply<replace<int, char>::apply<int, char, bool>>
    

    但请注意,这意味着您不是将单个 std::tuple 视为类型,而是将其视为类型列表。

    【讨论】:

    • 你能专门使用一个模板来链接replace&lt;F1, T1&gt;::type&lt;replace&lt;F2, T2&gt;::type&lt;A, B, C, D&gt;&gt;吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多