2012-04-04 147 views
42

是否允许通过引用传递数组?C++通过引用传递数组

void foo(double& *bar) 

似乎我的编译器说不。为什么?什么是通过引用传递数组的正确方法?还是解决办法?我有一个数组参数,我的方法应该修改,然后我应该检索。另外,我可以使这个数组成为一个类的成员,这很好,但它对我的代码的其他部分(我想避免)有很多缺点。

感谢和问候。

+0

它是什么编译器? – RedX 2012-04-04 09:02:20

+17

检查[顺时针螺旋规则](http://c-faq.com/decl/spiral.anderson.html)。 – 2012-04-04 09:03:31

+1

你有没有考虑过使用'std :: vector'或类似的东西? – moooeeeep 2012-04-04 09:06:10

回答

74

数组只能通过引用传递,实际上是:

void foo(double (&bar)[10]) 
{ 
} 

这可以防止您做这样的事情:

double arr[20]; 
foo(arr); // won't compile 

为了能够为任意大小的数组传递给foo,使它模板并在编译时捕获数组的大小:

template<typename T, size_t N> 
void foo(T (&bar)[N]) 
{ 
    // use N here 
} 

你应该认真考虑使用std::vector,或者如果你有一个支持C++ 11,std::array的编译器。

+5

“仍然,一旦传递给'foo',数组衰减到指针”。不,它不会,因为只能传递10个元素的数组,所以不需要关于大小的更多信息。 (再一次,你不能传递一个数组到'void foo(double * &)';)隐式转换的结果是一个右值,不能用于初始化非const的引用,你必须使用void foo(double * const &);'。 – 2012-04-04 09:40:28

+0

好吧,我纠正了,我删除了有争议的部分。 – jrok 2012-04-04 09:46:53

+0

很棒:)这正是我想要的。我在模板中做了void foo(T&bar [N])'但实际上意味着“引用数组”而不是“引用数组” – OLL 2015-11-05 11:23:48

5

如果你想修改刚刚元素:

void foo(double *bar); 

就足够了。

如果要修改地址(例如:realloc),但它并不适用于阵列工作:

void foo(double *&bar); 

是正确的形式。

+3

除了你不能将数组传递给后者。他问了数组,而不是指针。 – 2012-04-04 09:28:05

+0

@JamesKanze:是的。第二种情况不适用于堆栈上的数组,在这种情况下,他应该使用第一种形式。 – Naszta 2012-04-04 09:30:53

+7

第二种情况不适用于数组,句点。它只有在你有一个指针类型的实际变量时才有效。 – 2012-04-04 09:41:34

1

像对方回答说的那样,把&后面的*

这提出了一个有趣的观点,有时候会引起混淆:类型应该从右到左读取。例如,这是(从最右边的*开始)指向指向int的常量指针的指针。

int * const *x; 

因此,您所写的内容是指向引用的指针,这是不可能的。

+0

更改顺序仍然不允许他传递数组。它需要一个实际的指针对象,而不是转换的结果。 – 2012-04-04 09:29:26

5

由于您使用的是C++,此处仍然缺少的强制性建议是使用std::vector<double>

您可以轻松地引用传递:

void foo(std::vector<double>& bar) {} 

如果你有C++ 11的支持,也看看std::array

参考:

+2

:-)是的。 'std :: vector'通常是最好的解决方案。但也有例外。 – 2012-04-04 09:28:50

+0

是的。 :) +1为'std :: vector' – Naszta 2012-04-04 09:31:57

8

是的,但是当一个引用参数匹配,隐式阵列 指针不是自动的,所以你需要像:

void foo(double (&array)[42]); 

void foo(double (&array)[]); 

注意,但是,当匹配,double [42]double []是 截然不同的类型。如果您有一个未知尺寸的数组,它将与第二个匹配,但不是第一个,如果您有一个包含42 元素的数组,它将匹配第一个,但不匹配第二个。(后者, 恕我直言,非常反直觉的。)

在第二种情况下,你也必须通过尺寸,因为 没有办法,一旦你里面的功能来恢复它。

+5

第二个不为我编译。 – jrok 2012-04-04 09:29:38

+0

对我来说也不是。我不知道这是由于编译器错误还是我忽略的标准。我从来没有想过要这样做。 (如果维度是模板参数,第一个非常有用,因为编译器会为您找出正确的维度。) – 2012-04-04 09:37:27

+3

我不相信第二个示例是符合C++标准的有效。顺便提一下,它不能用GCC 4.8或Clang 3.4进行编译。我认为模板大小是必需的。 – Ricky65 2014-05-18 12:13:46

0

8.3.5.8如果参数的类型包括“与结合的T未知的数组指针”或类型的形式是“参考 与结合的T未知的阵列”,该程序是非法的构造