我想做的是这样的事情:
void dosth(bool& a) {
a[2] = false;
}
int main() {
bool a[10];
dosth(a);
return 0;
}
我想通过引用调用,数组作为参数。怎么实现这个?
THX
答案 0 :(得分:8)
像这样:
typedef bool array_type[10];
void dosth(array_type& a)
{
a[2] = false;
}
int main()
{
array_type a;
dosth(a);
}
或没有typedef:
void dosth(bool (&a)[10])
{
a[2] = false;
}
int main()
{
bool a[10];
dosth(a);
}
或更一般地说:
template <size_t Size>
void dosth(bool (&a)[Size])
{
/*static_*/assert(Size > 2);
a[2] = false;
}
int main()
{
bool a[10];
dosth(a);
}
如果你不在C ++ 0x中,你可以像这样实现一个(简单)static_assert
:
template <bool>
struct static_assert_type;
template <> // only true is defined
struct static_assert_type<true> {}
#define static_assert(x) { static_assert_type<(x)>(); }
如果数组大小太小,可以取消注释static_assert
并获得编译时错误。
答案 1 :(得分:5)
您可以允许数组衰减为指针,如Philippe的答案。
是一种更加类型安全的解决方案,它只接受数组并允许编译时范围检查template <size_t SIZE>
void dosth(bool (&a)[SIZE])
{
a[2] = false;
}
如果编译器不支持static_assert(SIZE > 2);
,您可以添加BOOST_STATIC_ASSERT(SIZE > 2);
(或static_assert
),如果索引超出范围,则会产生编译错误。
答案 2 :(得分:2)
这有点棘手,简单的方法(以及C中唯一可用的方法)是将函数的签名定义为获取指针:
void dosth( bool* a );
数组将自动衰减成为指向第一个元素的指针,只要你足够小心,它就会起作用。请注意,void dosth( bool a[10] )
正好是上面的签名:编译器会为您翻译它。
由于几个原因,这是不安全的,首先是它允许调用者传递任何大小的数组,甚至根本不传递数组(dosth(0);
)。
通过使用引用,可以在C ++中使用typeafe:
void dosth( bool (&a)[ 10 ] );
现在,编译器将确保将正好10个bool的数组传递给函数。这里有一些含义,首先是不仅用户不能传递空指针,而且她只能传递一个包含10个元素的数组,因此在以后访问第三个元素时不必担心溢出on(a[2]=false;
)。
另一方面,它限制了可用性,因为用户无法传递超过10个元素的数组,也无法传递动态分配的数组(new bool[10]
)。这可以通过使用模板来改进:
template <std::size_t N>
void dosth( bool (&a)[N] ) {
static_assert( N >= 10 );
//...
}
编辑:我打算回复塞德里克的评论,但这可能太长了。你是对的,它使动态分配的问题得不到解决。正如@GMan所说,在一般情况下,您希望使用其他数据类型来处理动态分配的内存。无论如何,有一种复杂的方法可以使用new[]
分配的内存来实现它,它不是那么直接。
问题是类型必须是bool [10]
,但new T[n]
会返回T*
而不是T[n]
。提供typedef也无济于事:
typedef bool b10[10];
b10* p = new b10; // error cannot convert from int* to int (*)[10]
您可以通过不请求单个数组而不是数组数组来克服该限制:
bool (*array)[10] = new bool[1][10];
dosth(*array);
但当然您需要使用delete []
而不是delete
:
delete [] array;
答案 3 :(得分:0)
如果要引用数组,可以执行以下操作。请注意,dosth
只接受对该大小的数组的引用,并且您将无法提供堆分配的数组(即bool* c = new bool[10]
)。
void dosth(bool (&a)[10]) {
a[2] = false;
}
int main() {
bool a[10];
bool (&aa)[10] = a;
dosth(a);
return 0;
}
答案 4 :(得分:-2)
您必须将参数声明为指针:
void dosth(bool* a) {
a[2] = false;
}
数组与指针
基本相同