【问题标题】:How to transform template to template pre C++11如何将模板转换为模板 pre C++11
【发布时间】:2020-02-20 10:39:18
【问题描述】:

this question触发,我写了一个模板,允许将模板转换为具有不同参数的模板:

template< template <int A,char B,bool> typename T>
struct Add_true {
    template <int A,char B> using type = T<A,B,true>;
};

背景:目的是将template&lt;int A, char B, bool C&gt; class A2{}; 作为模板模板参数传递给template&lt;template&lt;int A, char B&gt; typename T&gt; class A1 {};。我学习了 C++11 的模板。一旦我习惯于编写接受类型和“返回”类型的类型/函数,而不是编写接受值和返回值的函数,我对代码的思考就发生了很大的转变。我从来没有想过,编写给定模板“返回”不同模板的模板也非常简单。问题是我一点也不知道如何在没有别名模板的情况下编写上述或类似的内容,这些模板仅在 C++11 之后才可用。以下是始终可能发生的事情。给定

template <int A,char B, bool C> struct Foo{};

我可以通过以下方式将布尔参数“绑定”到Foo

template <int A,char B>
struct Add_true_to_Foo {
     typedef Foo<A,B> type;
};

但是现在Add_true_to_Foo&lt;A,B&gt;::type 不是模板,如果没有 C++11,我一点也不知道如何编写一个不仅适用于 Foo 也适用于

template <int A,char B, bool C> struct Bar{};

也许我遗漏了一些明显的东西。我的问题是

在C++11之前可以写出和上面Add_true等价的东西吗?

【问题讨论】:

    标签: c++ templates c++03 template-templates


    【解决方案1】:

    没有 C++11 模板的严格等价物使用, 但是您可以添加额外的模板类来模仿行为并使用不同的语法:

    template <template <int, char, bool> class C>
    struct Add_true {
        template <int A, char B>
        struct apply
        {
            typedef T<A, B, true> type;
        }
    };
    

    有用法:

    template <int A,char B, bool C> struct Foo{};
    
    typedef Add_true<Foo>::apply<42, '*'>::type my_type; // Foo<42, '*', true>
    

    【讨论】:

    • 不确定我是否理解这个答案。我可以将其用作template&lt;template&lt;int A, char B&gt; typename T&gt; class A1 {}; 的参数吗?我没有看到,但无论如何我将不得不花一些时间来解决这个问题,无论如何,谢谢你的回答
    • 好的,我想我明白了。在A1 中,我必须使用T::type,但如果可能的话,我想避免这种情况。对不起,如果问题不够清楚
    • StoryTeller 的回答 - Unslander Monica 将拥有您想要的语法(-> 模板类型),但需要注意的是该类型并非您想要的(但源自您想要的)可直接在A1 中使用。我的解决方案确实需要将A1 更改为额外的typename /*..*/::type
    • 所以我没有直接问的问题的答案是“是的”。我仍然感到惊讶,我的意思是这里应用的技术对我来说并不是全新的,但是我链接的问题让我从全新的角度看待事物
    【解决方案2】:

    继承将是 C++03 方式

    template< template <int A,char B,bool> typename T>
    struct Add_true {
        template <int A,char B>
        struct type : T<A,B,true> {};
    };
    

    在 C++11 和 C++03 中,type 是新模板的名称。区别仅在于专业化的含义。对于别名模板,它们完全代表被别名的东西,而在这里它们是新类型。但是,派生到基础的转换应该允许将 C++03 type 专业化几乎完全视为它们的“别名”。

    【讨论】:

    • 我不喜欢那里的继承......没有简单的方法来单独检索T&lt;A, B, true&gt;
    • @Quentin - 是的,这就是别名模板被引入并且更优越的原因。但是如果你仅限于 C++03 并且你的目标是创建一个新模板(而不是说,做类似std::allocator::rebind 的事情)。然后就是这样。
    • 谢谢,我必须花一些时间才能接受答案。
    【解决方案3】:

    在 C++03 中,我们没有模板别名,但同样可以使用如下结构模板实现:

    template<template<int A, char B> class T> class A1
    {
        typedef typename T<1, 'a'>::type actual_A2;
    };
    
    template<int A, char B, bool C> class A2 {};
    
    template< template<int A, char B, bool C> class T >
    struct Add_true
    {
        template<int A, char B>
        struct apply
        {
            typedef T<A, B, true> type;
        };
    };
    typedef Add_true<A2> A2_with_true;
    
    A1< A2_with_true::apply > a1;
    

    请注意,您需要更改A1 的工作方式,因为它必须使用嵌套的type typedef 才能获得实际的A2 特化。

    【讨论】:

    • 抱歉,您的“简化”方向错误。如果您阅读了我链接的问答,您的 A2_with_true 就是 OP 在问题中的内容,而且您的 C++03 解决方案也不是我想要的,因为您的 A2_with_true 仅将 true 绑定到 A2 但是要为FooBar 做同样的事情,我将不得不写一个Foo_with_trueBar_with_true,这正是要避免的
    • 问题并不清楚,但我更新了答案以定义Add_true
    • 我对另一个问题也有同样的疑问。现在您传递给A1 的参数不是类型本身,而是在A1 内部我必须使用T::type 来获得所需的类型,不是吗?
    猜你喜欢
    • 2021-11-21
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 2017-05-07
    相关资源
    最近更新 更多