C++中数组返回的简单方法 我试图在C++中使用下面的ID函数。我会认为我可以简单地做到 typedef int v3[3]; v3 & id( v3 & in ) { in[0] = in[1] = in[2] = 1; return in; } int main() { v3 & v = id( v ); return 0; }

C++中数组返回的简单方法 我试图在C++中使用下面的ID函数。我会认为我可以简单地做到 typedef int v3[3]; v3 & id( v3 & in ) { in[0] = in[1] = in[2] = 1; return in; } int main() { v3 & v = id( v ); return 0; },c++,arrays,reference,pass-by-reference,C++,Arrays,Reference,Pass By Reference,然而,这导致了g++的一个错误,这对我来说并不清楚。因为我可以使用标量类型执行以下操作: int & zero( int & in ) { in = 0; return in; } int main() { int i = zero( i ); return 0; } 如何将id与一行代码一起使用?我希望避免一个丑陋的解决方案,例如: int main() { v3 v; v3 & w = id( v ); } 当然,我不想使用std::ve

然而,这导致了g++的一个错误,这对我来说并不清楚。因为我可以使用标量类型执行以下操作:

int & zero( int & in )
{
  in = 0;
  return in;
}

int main()
{
  int i = zero( i );
  return 0;
}
如何将id与一行代码一起使用?我希望避免一个丑陋的解决方案,例如:

int main()
{
  v3 v;
  v3 & w = id( v );
}
当然,我不想使用std::vector或std::array c++11。所以我真的很感兴趣为什么我的天真解决方案实际上是未定义的行为

编辑:std::vector将需要动态分配,在我的情况下,应该避免我需要操纵数千vr3。我不能使用std::array,因为我必须坚持使用c++03。显然,人们猜不到我的要求。

这是:

v3 & v = id( v );
这是:

int i = zero( i );
都是胡说八道,因为你不能在它自己的初始值中使用某些东西。有些编译器会警告您这一点,但有些不会

您可以制作一个宏:

#define V3_UNIT {1,1,1}
现在您可以执行以下操作:

v3 v = V3_UNIT;
PTHREAD\u MUTEX\u初始值设定项是这种技术在野外的一个常见示例。

使用:


可以用大括号{}来表示初始值。 Like:in={1,1,1}

我真的很感兴趣,为什么我的天真解决方案实际上是未定义的行为

这是因为:您使用id的返回值初始化引用v,id返回作为其参数的引用。传递给id的参数是v,因此可以使用未初始化的self初始化v,而无需分配要引用的对象

如何将id与一行代码一起使用

好的,您只需在一行中键入两条语句,就可以消除冗余赋值:

v3 v; id(v);
但是,更简单的做法是:

v3 v{1, 1, 1};
我需要返回一个数组

如果你仔细阅读,你会发现你运气不好。数组不能作为参数返回或传递。您可以做的是使用一个包装类来保存数组。但是没有必要自己实现它,因为标准库已经提供了一个:std::array

当然,我不想使用std::vector或std::array


你把自己画进了一个角落,有着相互矛盾的欲望。然后您需要自己重新实现std::array。我不建议您这样做。

您的问题是,在v案例中的示例main中,您没有v3。您只有对V3的引用,没有任何内容可供参考


在int的情况下,你可以不受惩罚,因为你有一个真正的int可以参考。但它很可能是未定义的行为-它肯定非常狡猾。

此代码是未定义的行为:

v3 & v = id( v );
在叮当声下,您将得到警告:

警告:引用“v”在其自身初始化中使用时尚未绑定到值[-Wuninitialized]

[编辑]

事实上,我不能100%确定引用的自分配是UB还是格式错误的代码,我发现了关于这个主题的有趣讨论:


这表明它的形式应该是相当不正确的——但看起来讨论正在进行中。对这类代码最常见的评论都是胡说八道,但我想这只是因为很难找到标准中关于这一点的适当部分。

所以UB相当于用叮当声发出警告?你能说得更具体些吗?@malat我已经更新了我的答案。警告并不总是指UB。你很幸运你得到了警告。这将导致运行时空引用异常,因为V没有初始化。@ FigaCART: C++中的空引用异常是什么?实际上,您可以在它自己的初始化器中使用一些东西——只要您使用它初始化引用或指针即可。您不能使用该值。@John Zwinck:与语言无关。CPU异常。关于MIPS it TLBLexception@FigaroCat如果出现CPU异常,您仍然相对幸运。这不是保证。正如我在帖子中所说的,我不能使用std::array或基于struct return的解决方案。我需要返回一个数组。@malat,但您没有返回数组,您返回的是对数组的引用。@malat是std::array或std::vector,它应该是C++11之前的首选解决方案,或者是丑陋的解决方案。除非您想动态分配内存,否则这就是您的选择,我真的不推荐。@malat您可以使用std::array并调用std::array::data,只要您必须将C数组传递给遗留代码。您可以为名为v的引用分配存储。当您执行v[0]=v[1]=v[2]=1;!时,它指向什么以及您在哪里编写;!?如果你对这个问题感兴趣,这是一个未定义的行为吗?编译器为什么要编译它?请看这里:我真的很感兴趣,什么是不使用std::vector或std::array的好理由。你一定很清楚,你告诉我们,你当然不想使用它们。关于这个问题,请再详细一点。谢谢你的明确解释!至少我现在明白我的错误了。
v3 & v = id( v );