使用具有固定长度数组typedef的new

时间:2011-03-23 13:29:11

标签: c++ typedef

如何为固定长度数组定义typedef,以便我也可以'new'。以下不起作用:

typedef double Vector[3];
Vector *v = new Vector; // does not compile

我们试图将一些旧的C代码包装到C ++中,这些代码以通用的方式处理float *float (*)[3]

4 个答案:

答案 0 :(得分:3)

class Vector
{
public: // methods
    double * data() { return mData; }
    const double * data() const { return mData; }
    double & operator[](int i) { return mData[i]; }
    double operator[](int i) const { return mData[i]; }
private: // attributes
    double mData[3];
};

将允许

Vector * pv = new Vector;
Vector & v = *pv;
v[0] = 1;
v[1] = 2;
v[2] = 3;

pass_it_to_legacy_lib(v.data());

delete pv;

原始示例的一个问题是,它会调用new运算符,其中new[]实际上是正确的。此外,如果必须使用delete[]而不是普通delete,则不明显。

班级方法不需要new[]并充分利用先验固定长度。

答案 1 :(得分:2)

指向double[3]的指针是double * - 所以这将起作用:

  typedef double Vector[3];
  double *v = new Vector;

但我建议你不要那样使用它 - 删除你需要数组删除操作符的数组:

  delete[] v;

但在new Vector上你没有看到它是一个数组,所以它可能会被遗忘。

此案例在Scott Meyers Effective C ++ 中得到处理(强烈建议避免)。所以最好不要在这里使用typedef。

答案 2 :(得分:0)

如果您乐意在C ++代码中使用模板,那么这样的东西可以工作..

template <typename T, int S>
struct array
{
  array() : _inst() {}

  template<typename _F>
  void operator()(_F & f)
  {
    f(_inst); 
  }

  operator T*() { return _inst; }

  // real array
  T _inst[S];
};

typedef array<double, 4> d4;

void foo(double*)
{

}

int main(void)
{
  d4 d; // no need for new, but you can use if you want

  // first way to call is to pass the function to the array object, which will then
  // visit
  d(foo);
  // take advantage of the type operator (operator T*)
  foo(d);
}

答案 3 :(得分:0)

#include <cassert>
#include <vector>

using namespace std;

template<typename Type, int Dimension>
const vector<Type> make_fixed_vector(const Type& value = Type())
{
    return vector<Type>(Dimension, value);
}

int main(void)
{
    vector<int> v3 = make_fixed_vector<int, 3>();
    assert(v3.size() == 3);
}

C ++ 1x编译器能够推导出变量的类型,这在使用这种技术声明多维“固定”向量时很方便:

    .
    .
    .
template<typename Type, int Rows, int Columns>
const vector<vector<Type> > make_fixed_vector_vector(const Type& value = Type())
{
    return vector<vector<Type> >(Rows, make_fixed_vector<Type, Columns>(value));
}

int main(void)
{
    auto vv = make_fixed_vector_vector<int, 3, 4>(42);

    assert(vv.size() == 3);
    assert(vv[0].size() == 4);
    assert(vv[0][0] == 42);
    assert(vv[2][3] == 42);
}

在为列表表达式编写解析器函数时,我有这个简单的想法,它将返回一个整数向量的固定大小的向量。例如,vector<vector<int> >(1)表达式为“(0,8)”,而vector<vector<int> >(2)表示像“(3-4)(5)”等表达式。在应用程序中,最多可以有5个带括号的定义,它们表示对程序数据的逻辑引用。我首先尝试解析vector<vector<int> >(5)。工作?好的,有参考类型A,最详细的一个。否则vector<vector<int> >(4)表示引用类型B等。

为此目的make_fixed_vector运作良好,但从一般角度来看,该技术存在缺陷。最值得注意的是,由于make_fixed_vector没有返回真正的类型,因此无法在编译时检查其维度。在运行时reserve,可以进行resizepush_back次呼叫。并且,由于函数模板不能具有默认模板参数,因此自定义分配器需要更多类型:

template<typename Type, int Dimension, template<typename> class Allocator>
const vector<Type Allocator<Type> > make_fixed_vector(const Type& value = Type())
{
    return vector<Type, Allocator<Type> >(Dimension, value);
}

vector<int> v3 = make_fixed_vector<int, 3, std::allocator>();

等。但是这种技术使小型项目保持基础。除非这种美德相关,否则Boost的boost::array可能会更加真实。