【问题标题】:partial specialize template with template argument带有模板参数的部分专门化模板
【发布时间】:2015-04-28 10:39:07
【问题描述】:

我有这个模板

template <typename T, size_t maxsiz = 6>
class Array;

我有这个适配器模板

template <typename T, template <typename> class Container = std::vector>
class Stack;

我想要做的是像这样使用带有堆栈的数组

Stack<int, Array> s;

但是,Array 的默认构造函数不能满足 Stack 的要求,所以我需要专门为 Array 设置 Stack。 理想情况下,我只想专门化 Stack&lt;T, Array&gt; 的 ctor,这样我就可以在初始化时为内部 Array 成员提供正确的参数。

我试过了

template <typename T>
class Stack<T, Array>::Stack() : container(0) {  }  // container is the name of the wrapped Container

然而,它有问题。首先,它不会编译(是的......),其次,我希望能够给数组一个不同的大小,像这样

Stack<int, Array<int, 13>> stack;

或任何功能等效的东西(数组大小的编译时间常数)。如何做到这一点?

更新

所以我做了更多的挖掘,显然如果没有整个类的相应部分特化,你就不能部分特化成员函数。这就解释了为什么我的尝试行不通。

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    与其将Stack 更改为与Array 一起使用,不如为Array 提供一个与Stack 一起使用的适配器:

    template <typename T>
    struct StackArray : Array<T> {
        StackArray()
            : Array<T>(0)
        { }
    
        // anything else that needs to change here
    };
    

    你可以这样做:

    Stack<int, StackArray> s;
    

    另外,您的Stack 模板不正确。您不能将std::vector 用作template &lt;typename&gt; class Container 的默认模板,因为std::vector 采用两个 模板参数。如果你做到了,它可能会更有用:

    template <typename T, typename Container = std::vector<T>>
    struct Stack { .. };
    

    那么我们也可以将maxsiz 参数添加到StackArray 并执行以下操作:

    Stack<int, StackArray<int, 13>> s;
    

    std::priority_queue 和 std::stack 就是这样设计的。

    【讨论】:

    • 哇,将Array 适配为Stack 的方法非常棒,我为什么没想到:) 修改模板签名以采用第二种类型而不是模板并不理想(因为我失去了一些类型安全),但因为maxsiz 这可能是唯一的方法。谢谢,我把它标记为已接受
    • @qweasd:你仍然可以检查(static_assert Container 是 T 容器,类似于 static_assert(std::is_same&lt;T, typename Container::value_type&gt;::value, "Bad type");)
    【解决方案2】:

    只需要一个明确的数组大小并使用类似的东西:

    template <typename T, int N>
    class Stack<T, Array<T, N>>::Stack() : Array<T, N> {  }
    

    用法:

    Stack<int, Array<int>> x;
    Stack<int, Array<int, 2>> y;
    

    【讨论】:

    • 我不确定这里发生了什么,这是构造函数专业化还是类专业化?无论如何,我逐字逐句尝试并修改。它不会编译,因为 Stack 类需要一个模板模板参数,而不是类型。
    • @qweasd 这是一个类专业化。它总是必须是模板模板参数吗?
    • 好吧,我想那会更好,因为那样Stack&lt;int, vector&lt;double&gt; s 就不会编译,这是可取的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多