return c++ 中数组的简单方法
Simple way to return an array in 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;
}
然而,这会导致 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)。所以我真的很感兴趣为什么我天真的解决方案实际上是 undefined behavior
.
编辑: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_MUTEX_INITIALIZER
是这种技术在野外的一个常见例子。
使用std::array
:
#include <array>
using v3 = std::array<int, 3>;
v3 id()
{
return {{ 1, 1, 1 }};
}
int main()
{
v3 v = id();
}
您可以在大括号 {} 中初始化值。
喜欢:in = {1,1,1};
I am really interested why my naive solution is actually undefined behavior.
它是 UB 因为:您使用 id
的 return 值初始化引用 v
,并且 id
return 是它的引用范围。传递给 id
的参数是 v
,因此您使用未初始化的自身初始化 v
,而无需分配要引用的对象。
How can I use id with a single line of code ?
好吧,您可以简单地在一行中键入两个语句(并去掉多余的赋值):
v3 v; id(v);
但是,这样做会更简单:
v3 v{1, 1, 1};
I need to return an array.
如果你仔细阅读this page,你会发现你运气不好。数组不能被 returned 或作为参数传递。你可以做的是使用一个包装器 class 来保存数组。但是不需要自己实现,因为标准库已经提供了一个:std::array
.
Of course I do not want to use std::vector or std::array
你已经把自己逼到了一个角落,因为你的需求相互矛盾。然后您需要自己重新实现 std::array
。我不建议你这样做。
您的问题是,在您的样本 main
中,在 v 情况下您没有 v3
anywhere。您只有 v3
的引用,没有任何内容可供他们引用。
你在 int
的情况下逃脱了它,因为你有一个真正的 int
可以参考。 (但这很可能是未定义的行为——它肯定非常狡猾。)
此代码是未定义的行为:
v3 & v = id( v );
在 clang 下你会得到警告:
warning: reference 'v' is not yet bound to a value when used within its own initialization [-Wuninitialized]
[编辑]
实际上我不是 100% 确定引用的自赋值是 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
,但我想这只是因为很难找到标准的适当部分。
我正在尝试在 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::vector
或std::array
(c++11)。所以我真的很感兴趣为什么我天真的解决方案实际上是 undefined behavior
.
编辑: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_MUTEX_INITIALIZER
是这种技术在野外的一个常见例子。
使用std::array
:
#include <array>
using v3 = std::array<int, 3>;
v3 id()
{
return {{ 1, 1, 1 }};
}
int main()
{
v3 v = id();
}
您可以在大括号 {} 中初始化值。
喜欢:in = {1,1,1};
I am really interested why my naive solution is actually undefined behavior.
它是 UB 因为:您使用 id
的 return 值初始化引用 v
,并且 id
return 是它的引用范围。传递给 id
的参数是 v
,因此您使用未初始化的自身初始化 v
,而无需分配要引用的对象。
How can I use id with a single line of code ?
好吧,您可以简单地在一行中键入两个语句(并去掉多余的赋值):
v3 v; id(v);
但是,这样做会更简单:
v3 v{1, 1, 1};
I need to return an array.
如果你仔细阅读this page,你会发现你运气不好。数组不能被 returned 或作为参数传递。你可以做的是使用一个包装器 class 来保存数组。但是不需要自己实现,因为标准库已经提供了一个:std::array
.
Of course I do not want to use std::vector or std::array
你已经把自己逼到了一个角落,因为你的需求相互矛盾。然后您需要自己重新实现 std::array
。我不建议你这样做。
您的问题是,在您的样本 main
中,在 v 情况下您没有 v3
anywhere。您只有 v3
的引用,没有任何内容可供他们引用。
你在 int
的情况下逃脱了它,因为你有一个真正的 int
可以参考。 (但这很可能是未定义的行为——它肯定非常狡猾。)
此代码是未定义的行为:
v3 & v = id( v );
在 clang 下你会得到警告:
warning: reference 'v' is not yet bound to a value when used within its own initialization [-Wuninitialized]
[编辑]
实际上我不是 100% 确定引用的自赋值是 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
,但我想这只是因为很难找到标准的适当部分。