首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用可变模板实现打字员替换操作

使用可变模板实现打字员替换操作
EN

Stack Overflow用户
提问于 2021-08-06 18:22:44
回答 1查看 64关注 0票数 0

我正在尝试为打字员的各种模板版本(受现代C++设计启发)实现一个现代C++设计元功能,到目前为止,我可以通过以下代码实现所需的结果:

代码语言:javascript
复制
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<T1, T2, T3>的形式返回打字员(有效地将T类型的所有出现替换为目标类型U)。

现在的问题是,当我试图不使用helper元函数PushFrontT时,将以Typelist<T1, Typelist<T2, Typelist<T3, Typelist<>>>>的形式创建嵌套的打字员结构,这是不正确的(尽管用U替换了T的所有实例)。

错误版本的代码如下:

代码语言:javascript
复制
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包装膨胀的副作用,但我不确定。

下面是一个检查上述代码的简单测试程序:

代码语言:javascript
复制
#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);
}

简而言之,我的问题是,在不使用外部助手元功能(如Typelist)的情况下,如何摆脱过度嵌套的PushFrontT

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-06 18:47:57

您可以简化您的代码,并使用

代码语言:javascript
复制
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>...>;
};

演示

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68686037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档