c++ - 一个简约的智能数组(容器)类模板

标签 c++ arrays metaprogramming containers

我已经编写了一个(数组)容器类模板(我们称它为智能数组)以便在 BREW 平台中使用它(它不允许许多 C++ 构造,例如 STD 库、异常、等。它有一个非常小的 C++ 运行时支持);在写这篇文章时,我的 friend 说 Boost 中已经存在类似这样的东西,称为 MultiArray,我试过了,但 ARM 编译器 (RVCT) 出现了 100 多个错误。没看过Boost.MultiArray的源码,最近才开始学习模板;模板元编程让我很感兴趣,尽管我不确定这是否严格来说可以这样分类。

所以我希望我所有的 C++ 爱好者们都来审查它 ~ 指出缺陷、潜在的错误、建议、优化等;诸如“您没有编写自己的 Big Three 之类的东西,这可能会导致……”。可能有任何批评会帮助我提高这门课,从而提高我的 C++ 技能。

编辑:我使用了std::vector,因为它很容易理解,稍后它将被替换为在 BREW 中工作的自定义书面 vector 类模板平台。此外,C++0x 相关语法(如 static_assert)也将在最终代码中删除。

smart_array.h

#include <vector>
#include <cassert>
#include <cstdarg>
using std::vector;

template <typename T, size_t N>
class smart_array
{
    vector < smart_array<T, N - 1> > vec;

public:
    explicit smart_array(vector <size_t> &dimensions)
    {
        assert(N == dimensions.size());

        vector <size_t>::iterator it = ++dimensions.begin();
        vector <size_t> dimensions_remaining(it, dimensions.end());

        smart_array <T, N - 1> temp_smart_array(dimensions_remaining);
        vec.assign(dimensions[0], temp_smart_array);
    }

    explicit smart_array(size_t dimension_1 = 1, ...)
    {
        static_assert(N > 0, "Error: smart_array expects 1 or more dimension(s)");
        assert(dimension_1 > 1);

        va_list dim_list;
        vector <size_t> dimensions_remaining(N - 1);

        va_start(dim_list, dimension_1);
            for(size_t i = 0; i < N - 1; ++i)
            {
                size_t dimension_n = va_arg(dim_list, size_t);
                assert(dimension_n > 0);
                dimensions_remaining[i] = dimension_n;
            }
        va_end(dim_list);

        smart_array <T, N - 1> temp_smart_array(dimensions_remaining);
        vec.assign(dimension_1, temp_smart_array);
    }

    smart_array<T, N - 1>& operator[](size_t index)
    {
        assert(index < vec.size() && index >= 0);
        return vec[index];
    }

    size_t length() const
    {
        return vec.size();
    }
};

template<typename T>
class smart_array<T, 1>
{
    vector <T> vec;

public:
    explicit smart_array(vector <size_t> &dimension) : vec(dimension[0])
    {
        assert(dimension[0] > 0);
    }

    explicit smart_array(size_t dimension_1 = 1) : vec(dimension_1)
    {
        assert(dimension_1 > 0);
    }

    T& operator[](size_t index)
    {
        assert(index < vec.size() && index >= 0);
        return vec[index];
    }

    size_t length()
    {
        return vec.size();
    }
};

示例用法:

#include "smart_array.h"
#include <iostream>
using std::cout;
using std::endl;

int main()
{
    // testing 1 dimension
    smart_array <int, 1> x(3);
    x[0] = 0, x[1] = 1, x[2] = 2;
    cout << "x.length(): " << x.length() << endl;

    // testing 2 dimensions
    smart_array <float, 2> y(2, 3);
    y[0][0] = y[0][1] = y[0][2] = 0;
    y[1][0] = y[1][1] = y[1][2] = 1;
    cout << "y.length(): " << y.length() << endl;
    cout << "y[0].length(): " << y[0].length() << endl;

    // testing 3 dimensions
    smart_array <char, 3> z(2, 4, 5);
    cout << "z.length(): " << z.length() << endl;
    cout << "z[0].length(): " << z[0].length() << endl;
    cout << "z[0][0].length(): " << z[0][0].length() << endl;
    z[0][0][4] = 'c'; cout << z[0][0][4] << endl;

    // testing 4 dimensions
    smart_array <bool, 4> r(2, 3, 4, 5);
    cout << "r.length(): " << r.length() << endl;
    cout << "r[0].length(): " << r[0].length() << endl;
    cout << "r[0][0].length(): " << r[0][0].length() << endl;
    cout << "r[0][0][0].length(): " << r[0][0][0].length() << endl;

    // testing copy constructor
    smart_array <float, 2> copy_y(y);
    cout << "copy_y.length(): " << copy_y.length() << endl;
    cout << "copy_x[0].length(): " << copy_y[0].length() << endl;

    cout << copy_y[0][0] << "\t" << copy_y[1][0] << "\t" << copy_y[0][1] << "\t" << 
        copy_y[1][1] << "\t" << copy_y[0][2] << "\t" << copy_y[1][2] << endl;

    return 0;
}

最佳答案

如果我理解你想从这种类型中得到什么:

简而言之,最好使用以下形式:

template < typename T_, unsigned N_ ><br/> struct t_array {<br/> /* ... */<br/> static const size_t Size = N_; typedef T_ T;<br/> T objects_[Size];<br/> };

出于多种原因如果您只需要一个固定大小和固定类型的数组。编译器可以做出很多安全的假设——在某些情况下,这将对象大小减少了 20%(与使用 std::vector 相比)。它还更快、更安全。如果你在任何地方都使用它们,那么你最终可能会创建更大的二进制文件(与使用 std::vector 相比)。

有一类<boost/array.hpp>你应该阅读。

抱歉,如果您觉得这没有帮助 - 我认为至少阅读一份常见的生产质量实现(在尝试新技术之前)会有所帮助。

关于c++ - 一个简约的智能数组(容器)类模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2757986/

相关文章:

c++ - QT服务器端写函数有错误(在线程0中停止...)

c++ - 通过引用返回 unique_ptr 的 vector

javascript - 如何将数组写入的字符串转换为真正的数组?

clojure:覆盖函数应用程序

c++ - 调用一个方法,并传入一个指向类的指针

c++ - std::vector 成员的移动语义

C:尝试初始化结构中的 char 数组时,分配错误中的类型不兼容

javascript - 如何使用js查找对象数组中的重复数据?

ruby - 我如何使用 Ruby 元编程来重构这个公共(public)代码?

c++ - 您在哪里找到有用的模板?