如何为固定长度数组定义typedef,以便我也可以'new'。以下不起作用:
typedef double Vector[3];
Vector *v = new Vector; // does not compile
我们试图将一些旧的C代码包装到C ++中,这些代码以通用的方式处理float *
和float (*)[3]
。
答案 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
,可以进行resize
和push_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
可能会更加真实。