【发布时间】:2020-06-08 20:34:56
【问题描述】:
如果我有一个简单的结构 Foo,像这样定义,它就是一个 POD:
#include <iostream>
#include <type_traits>
struct Foo {
int a;
int b;
bool c;
};
int main() {
std::cout << (std::is_pod<Foo>::value ? "POD" : "NON POD") << '\n'; // Prints "POD"
}
现在假设我想默认初始化成员并直接执行:
struct Foo {
int a;
int b;
bool c = true;
};
结构不再是 POD!即使有这样的构造函数:
struct Foo {
int a;
int b;
bool c;
Foo() : a(0), b(0), c(false) {}
};
Foo 已经失去了它的 POD...
现在棘手的部分开始了。想象一下,我想添加一个采用a 的构造函数:
struct Foo {
int a;
int b;
bool c;
Foo(int a) : a(a), b(0), c(false) {}
};
现在 Foo 绝对不是 POD。但是如果添加一个默认构造函数:
struct Foo {
int a;
int b;
bool c;
Foo() = default;
Foo(int a) : a(a), b(0), c(false) {}
};
Foo 现在是一个 POD!
如您所见,即使我只是想使用第二个示例中的默认值,我也失去了 POD 性,但只要我定义一个显式的默认构造函数,我就可以重新获得它。
所以问题是:我们是否应该总是添加一个默认构造函数,以便我们可以从类的 POD 中受益并提高性能?仅仅因为我想默认初始化一些成员而失去性能真是太糟糕了......
换句话说,像在第二个示例中那样定义默认值会使结构非 POD 和非平凡,这在性能方面很糟糕,那么我如何才能默认初始化值并保持结构平凡?一个简单的解决方案是定义一个返回默认初始化 Foo 的 initFoo 函数,例如:
Foo initFoo() {
Foo foo;
foo.a = 0;
foo.b = 1;
foo.c = true;
return foo;
}
但这不是非常 C++,但无论如何它是正确的做法吗?
【问题讨论】:
-
POD 必须满足许多要求。拥有一个简单的默认构造函数并不会自动使其成为 POD。在大多数情况下,
struct是class。 -
为什么你认为类是 POD 会提高性能?即便如此:性能,什么操作,究竟是什么?您是否对您的代码进行了分析,以确保将您的类作为 POD,在您使用它们的任何用例中都能带来更好的性能?
-
请注意
std::is_pod现在(以及在实际发布 C++20 时)已弃用。 PODness 是一个正在被移除的概念。 -
@Ron 当然我认为结构的其余部分是符合 POD 的,这里我只是在谈论具有默认值。
-
一个可能的答案是:不,你不应该总是为你的类添加一个默认构造函数,假设你会从 POD-nes 和性能中受益。