【问题标题】:best practice to avoid partial specialization of alias templates避免别名模板部分特化的最佳实践
【发布时间】:2018-08-11 05:47:06
【问题描述】:

我现在正致力于实现一个标准,规范中定义了一个模板类vector_class。我只是使用了别名模板

template <class T, class Allocator=std::allocator<T>>
using vector_class = std::vector<T, Allocator>;

在后面的工作中,我有一个函数调用vector_class::data(),它返回一个类型为T*的指针。

除了Tbool 之外,一切正常。众所周知,std::vector&lt;bool&gt;std::vector 类型bool 的一个可能节省空间的特化,它没有实现成员函数data,实际上我的返回类型vector&lt;bool&gt;::data()机器是void。现在问题来了,我们有一些类似的代码:

template <class T>
class A {
public:
    vector_class<T> buffer;

    T* ptr; // this pointer is defined in the specification thus it is indispensable

    A(T* data, size_t size) {
        buffer.resize(size);
        ptr = buffer.data();
        std::copy(data, data + size, ptr);
    }
};

如果Tbool,编译器将在代码ptr = buffer.data() 中引发无法将类型void 转换为bool* 的错误。

嗯,对于我当前的实现,这是避免使用 std::vector 的最后一个选项,但在 Boost.我期望的是类似于别名模板的部分专业化,但不幸的是,根据 C++ 标准,这是不允许的。所以,我想问一下,有没有其他方法可以处理这样的问题?

【问题讨论】:

    标签: c++ templates vector stl


    【解决方案1】:

    您可以对代理类进行部分特化以与别名模板一起使用:

    template<typename T, typename Allocator> class
    vector_class_impl final
    {
        public: using type = std::vector<T, Allocator>;
    };
    
    template<typename Allocator> class
    vector_class_impl<bool, Allocator> final
    {
        public: using type = something_else<bool, Allocator>;
    };
    
    template <typename T, typename Allocator = std::allocator<T>>
    using vector_class = typename vector_class_impl<T, Allocator>::type;
    

    【讨论】:

    • 是的,这是一个很好的解决方案。现在我想我的步骤是专门为bool 实现一个容器。谢谢。
    【解决方案2】:

    这可能无济于事,因此您需要做更多的工作:

    template <class T, class Allocator=std::allocator<T>>
    struct vector_class: std::vector<T, Allocator>
    {
        using std::vector<T, Allocator>::vector;
            // and member types too
    };
    
    template<class Allocator>
    struct vector_class<bool, Allocator>
    {
        // recreate the whole vector interface here
    };
    

    【讨论】:

    • 谢谢。这样,我只需要重写所有必要的构造函数。
    【解决方案3】:

    我认为您可以将整个class A 模板专门用于bool,将vector_bool&lt;T&gt; 替换为boost::container::vector&lt;T&gt; 之类的其他内容。

    【讨论】:

    • 是的,如果class A中没有太多代码,这也是一个好方法,但是除了buffer之外,其他代码只是从常见的class A中处理的,使得很难维护。此外,如果我决定使用boost,为什么不直接使用它作为别名呢? :)
    • @tianshilei1992 这可以通过为主模板和特化提供通用模板基类来解决。
    猜你喜欢
    • 2019-04-03
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2016-11-25
    • 1970-01-01
    相关资源
    最近更新 更多