通过替换类型重写参数包

时间:2018-04-25 11:59:23

标签: c++ variadic-templates

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

#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次呼叫吗?

1 个答案:

答案 0 :(得分:4)

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

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视为一种类型,而不是类型列表。