在c ++中返回数组的简单方法

时间:2015-12-22 11:31:44

标签: c++ arrays reference pass-by-reference

我正在尝试在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;
}

然而,这会导致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::vectorstd::array(c ++ 11)。所以我真的很感兴趣为什么我的天真解决方案实际上是undefined behavior

编辑:std::vector将需要动态分配,在我的情况下应该避免(我需要操纵数以千计的vr3)。我无法使用std::array,因为我需要坚持c++03。显然,人们无法猜测我的要求。

6 个答案:

答案 0 :(得分:5)

此:

v3 & v = id( v );

而且:

int i = zero( i );

是胡说八道,因为你不能在自己的初始化程序中使用某些东西。有些编译器会对此发出警告,但有些则不会。

你可以制作一个宏:

#define V3_UNIT {1,1,1}

现在你可以做到:

v3 v = V3_UNIT;

PTHREAD_MUTEX_INITIALIZER是这项技术的一个常见例子。

答案 1 :(得分:4)

使用std::array

#include <array>

using v3 = std::array<int, 3>;

v3 id()
{
  return {{ 1, 1, 1 }};
}

int main()
{
  v3 v = id();
}

答案 2 :(得分:4)

  

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

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

  

如何在一行代码中使用id?

好吧,你可以简单地在一行上输入两个语句(并删除冗余的赋值):

v3 v; id(v);

但是,它会更简单:

v3 v{1, 1, 1};
  

我需要返回一个数组。

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

  

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

你已经把自己描绘成了一个有冲突欲望的角落。您需要自己重新实现std::array。我不建议你这样做。

答案 3 :(得分:2)

您的问题是,在您的样本中main,如果您没有v3 。您只能引用v3,并且没有任何内容供他们参考。

你在int案例中侥幸成功,因为你有真正的真实int可以参考。 (但它可能是未定义的行为 - 它当然非常狡猾。)

答案 4 :(得分:1)

此代码是未定义的行为:

v3 & v = id( v );

在clang下你会收到警告:

  

警告:在自己的初始化中使用引用'v'尚未绑定到某个值[-Wuninitialized]

[编辑]

实际上我并不是百分之百确定如果自我指定引用是UB或格式错误的代码,我发现有关此主题的有趣讨论:

Why is GCC tricked into allowing undefined behavior simply by putting it in a loop? http://www.open-std.org/pipermail/ub/2014-September/000506.html

这表明它应该是相当不合理的 - 但看起来讨论正在进行中。关于此类代码的最常见评论是nonsense,但我想这只是因为很难找到相应的标准部分。

答案 5 :(得分:0)

您可以在大括号{}中初始值。 喜欢:in = {1,1,1};