【问题标题】:implementing typelist replace operation using variadic templates使用可变参数模板实现类型列表替换操作
【发布时间】:2021-08-06 18:22:44
【问题描述】:

我正在尝试为类型列表的可变参数模板版本实现 ReplaceAll 元函数(受 Modern C++ Design 启发),到目前为止,我可以使用以下代码实现预期的结果:

template <typename... Elements> struct Typelist {};

//
// helper metafunction to set "Head" of typelist
//
template <typename TList, typename T> struct PushFrontT;

template <typename... Elements, typename T>
struct PushFrontT<Typelist<Elements...>, T> {
    using Result = Typelist<T, Elements...>;
};

//
// metafunction to replace all occurences of "T" with "U"
//
template <typename TList, typename T, typename U> struct ReplaceAll;

template <typename T, typename U>
struct ReplaceAll<Typelist<>, T, U> {
    using Result = Typelist<>;
};

template <typename... Tail, typename T, typename U>
struct ReplaceAll<Typelist<T, Tail...>, T, U> {
    using Result = typename PushFrontT<
        typename ReplaceAll<Typelist<Tail...>, T, U>::Result, U
    >::Result;
};

template <typename Head, typename... Tail, typename T, typename U>
struct ReplaceAll<Typelist<Head, Tail...>, T, U> {
    using Result = typename PushFrontT<
        typename ReplaceAll<Typelist<Tail...>, T, U>::Result, Head
    >::Result;
};

它以Typelist&lt;T1, T2, T3&gt; 的形式返回一个类型列表(有效地将所有出现的T 类型替换为目标类型U)。

现在的问题是,当我尝试不使用辅助元函数 PushFrontT 时,将以 Typelist&lt;T1, Typelist&lt;T2, Typelist&lt;T3, Typelist&lt;&gt;&gt;&gt;&gt; 的形式创建嵌套类型列表结构,这是不正确的(尽管将 T 的所有实例替换为 @987654330 @)。

错误版本的代码如下:

template <typename T, typename U>
struct ReplaceAll<Typelist<>, T, U> {
    using Result = Typelist<>;
};

template <typename... Tail, typename T, typename U>
struct ReplaceAll<Typelist<T, Tail...>, T, U> {
    using Result = Typelist<U,
        typename ReplaceAll<Typelist<Tail...>, T, U>::Result
    >;
};

template <typename Head, typename... Tail, typename T, typename U>
struct ReplaceAll<Typelist<Head, Tail...>, T, U> {
    using Result = Typelist<Head,
        typename ReplaceAll<Typelist<Tail...>, T, U>::Result
    >;
};

基于我对可变参数模板的有限了解,我认为额外的Typelist 是pack expansion 的副作用,但我不确定。
这是一个简单的测试程序来检查上述代码:

#include <type_traits>

int main () {
    using tlist = Typelist<int, char, int, double>;

    static_assert(
        std::is_same<
        typename ReplaceAll<tlist, int, long>::Result,
        Typelist<long, char, long, double>>::value,
        "Incorrect typelist!"
    );

    return(0);
}

简而言之,我的问题是如何在不使用 PushFrontT 等外部辅助元函数的情况下摆脱过度嵌套的 Typelists?

【问题讨论】:

    标签: c++ variadic-templates typelist


    【解决方案1】:

    您可以简化代码并摆脱递归

    template <typename TList, typename T, typename U> struct ReplaceAll;
    
    template <typename ... Ts, typename T, typename U>
    struct ReplaceAll<Typelist<Ts...>, T, U>
    {
        using Result = Typelist<std::conditional_t<std::is_same_v<Ts, T>, U, Ts>...>;
    };
    

    Demo

    【讨论】:

      猜你喜欢
      • 2013-09-13
      • 2020-12-15
      • 1970-01-01
      • 2016-01-22
      • 2016-04-13
      • 2015-08-09
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      相关资源
      最近更新 更多