如何使用未知大小的boost :: array作为对象变量

Mic*_*han 17 c++ arrays templates boost class

我想使用boost :: array作为类成员,但我不知道编译时的大小.我想到了这样的东西,但它不起作用:

int main() {
    boost::array<int, 4> array = {{1,2,3,4}};
    MyClass obj(array);
}

class MyClass {
    private:
        boost::array<int, std::size_t> array;
    public:
        template<std::size_t N> MyClass(boost::array<int, N> array)
        : array(array) {};
};
Run Code Online (Sandbox Code Playgroud)

编译器gcc说:

error: type/value mismatch at argument 2 in template parameter list for
  ‘template<class _Tp, long unsigned int _Nm> struct boost::array’
error:   expected a constant of type ‘long unsigned int’, got ‘size_t’
Run Code Online (Sandbox Code Playgroud)

这显然意味着不能使用可变大小的数组作为类成员.如果是这样,这将否定boost :: array相对于向量或标准数组的所有优点.

你能告诉我我做错了什么吗?

小智 19

升压的阵列是基于所述第二模板参数固定大小,并且boost::array<int,4>是一个不同类型boost::array<int,2>.您不能拥有同一类的实例(在您的示例中为MyClass),这些实例的成员具有不同的类型.

但是,std :: vectors可以有不同的大小而不是不同的类型:

struct MyClass {
  template<std::size_t N>
  explicit
  MyClass(boost::array<int, N> const& array)
  : data(array.begin(), array.end())
  {}

private:
  std::vector<int> data;
};

int main() {
  boost::array<int, 4> a = {{1,2,3,4}};
  MyClass obj(a);

  boost::array<int, 2> a2 = {{42,3}};
  MyClass obj2(a2);

  // notice obj.data.size() != obj2.data.size()

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

也就是说,boost :: array仍然有用(它在这个示例代码中甚至有用),只是没有你想要使用它的确切方式.


Kor*_*icz 12

你错过了一些基本要点.你可以有:

  1. 一个静态分配的数组-char arr[10];
  2. 动态分配的数组-char* arr = new arr[10];

第一个的大小在编译期间是已知的(因为大小是常量),因此您可以为它预先分配内存空间,另一个不是,因此您需要在运行时为其分配内存.

STL/TR1/Boost 为两种类型的数组提供包装器.这些不仅包括对手的包装,也包括安全性(在某些情况下进行范围检查)和电源(迭代器).对于这两种情况,我们有一个单独的包装器:

  1. 静态分配的数组包装器 boost::array<char,10> arr;
  2. 动态分配的数组包装器 std::vector<char> arr;

除了可动态分配之外,后者还具有自我调整大小和允许调整大小的优点.boost::array另一方面,模仿一个type arr[const]结构.

因此,您需要决定是要让类具有静态分配的内存还是动态分配内存.前者只有在类存储是固定大小或几个固定大小之一时才有意义.后者在所有其他情况下都有意义.

静态分配将使用模板

template < size_t N >
class MyClass {
private:
    boost::array< int, N > array;
public:
   MyClass(boost::array< int, N > array) : array(array) {};
};

// ...

boost::array<int, 4> array = {{1,2,3,4}};
MyClass<4> obj(array);
Run Code Online (Sandbox Code Playgroud)

但是会为每个类的大小创建单独的代码,并且它们不会互操作(尽管可以绕过这个).

动态分配将使用向量

class MyClass {
private:
    std::vector< int > array;
public:
   MyClass(const std::vector< int >& array) : array(array) {};
};
Run Code Online (Sandbox Code Playgroud)

不要害怕向量,将它们视为动态分配的数组 - 向量的大小调整是一个额外的好处,几乎根本不会影响性能.


Nik*_*sov 6

我建议使用boost :: scoped_array吗?另一方面,您可能不希望每次都实际复制整个数组.那么boost :: shared_array将是更好的选择.