C++ 在非POD结构优先于类的情况下,是否存在有效的用例?

C++ 在非POD结构优先于类的情况下,是否存在有效的用例?,c++,class,struct,language-history,C++,Class,Struct,Language History,根据(2003)标准对结构的定义,它是类的特殊情况,成员、函数和基类具有不同的默认访问修饰符。它还将定义结构的需求,使其成为POD结构 C++2003标准,ISO 14882第9.0.4节: 结构是用类键结构定义的类;其成员和基类(第10条)是公共的 默认情况下(第11条)。联合是用类键联合定义的类;其成员由公众人士担任 默认值,一次只保存一个数据成员(9.5)。[注:类别类型的聚合在 8.5.1.]POD结构是一个聚合类,它没有非POD结构类型的非静态数据成员, 非POD联合(或此类类型的数组

根据(2003)标准对结构的定义,它是类的特殊情况,成员、函数和基类具有不同的默认访问修饰符。它还将定义结构的需求,使其成为POD结构

C++2003标准,ISO 14882第9.0.4节:

结构是用类键结构定义的类;其成员和基类(第10条)是公共的 默认情况下(第11条)。联合是用类键联合定义的类;其成员由公众人士担任 默认值,一次只保存一个数据成员(9.5)。[注:类别类型的聚合在 8.5.1.]POD结构是一个聚合类,它没有非POD结构类型的非静态数据成员, 非POD联合(或此类类型的数组)或引用,并且没有用户定义的复制分配运算符 并且没有用户定义的析构函数。类似地,POD联合是没有非静态数据的聚合联合 类型为non-POD struct、non-POD union(或此类类型的数组)或reference的成员,并且没有用户定义的 复制赋值运算符,无用户定义的析构函数。POD类是一个 POD结构或POD联合

根据这个定义,非POD结构和类之间唯一的区别是默认的访问修饰符

以下是我可以想象的拥有非POD结构的目的:

  • 它们是一个遗留特性,需要维护以实现向后兼容性
  • 键入
    public:
    很难
当其他系统认为非POD结构是POD结构时,使用非POD结构可能会带来痛苦,例如,在传递给C和返回时。举例说明。由于默认情况下编译器不会静态断言POD结构,因此当在只能使用POD结构的上下文中使用该结构时,应用程序将在运行时崩溃。更糟糕的是,我可以想象(尽管我不知道这是否可能)一个非POD结构在某些需要POD的情况下工作,而在其他情况下失败,导致错误和崩溃,这是非常难以追踪的


在某些情况下,拥有非POD结构可能会导致奇怪和不正常的行为,非POD结构有什么用处?为什么编译时静态结构不检查POD的正确性(通过STD:C++中的ISSpod或Boost等价物)?< /P> < P>我认为这是一个毫无意义的历史性事故,坦率地说,在C++中根本不应该添加“<代码>类< /Cord>关键字”。哦,好吧

如果一个
struct
被要求是POD,这通常会让人恼火——你通常从POD开始,仅仅因为你可以,就称它为“struct”,然后当你决定将它变成非POD时,不得不在很多地方更改它


请注意,GCC(至少直到最近)并不关心您(转发)是否在某个位置将某个对象声明为类,在其他位置将其声明为结构,反之亦然。CLAN抱怨这类事情(尽管它有权做任何事情,尽管这会破坏某些现有代码)。

< P>我认为这是一个毫无意义的历史性事故,坦率地说,“代码>类< /code >关键字根本不应该在C++中添加。哦,好吧

如果一个
struct
被要求是POD,这通常会让人恼火——你通常从POD开始,仅仅因为你可以,就称它为“struct”,然后当你决定将它变成非POD时,不得不在很多地方更改它

请注意,GCC(至少直到最近)并不关心您(转发)是否在某个位置将某个对象声明为类,在其他位置将其声明为结构,反之亦然。Clang抱怨这类事情(它完全有权这样做,尽管这确实“破坏”了一些现有代码)

“默认情况下,编译器不会静态断言POD ness”

哦?

#包括//std::cout,std::endl
#include//std::is_pod
#包括//std::string,std::to_string
使用名称空间std;
结构A
{
int x;
};
结构B
{
字符串s;
};
int main()
{
静态布尔常数a=is_pod::value;
静态断言(a,“啊…”);
静态断言(!is_pod::value,“Bah!”);
}
<>代码>结构> <代码>允许的是非POD,例如上面的代码> B>代码>,即为什么语言是这样设计的,这可能在Bjarne Stroustrup的《C++设计与演化》一书中找到。如果没有,那么可能只有比亚恩自己知道。因为 >结构> <代码>的C++通用性从一开始就存在。 “默认情况下,编译器不会静态断言POD ness”

哦?

#包括//std::cout,std::endl
#include//std::is_pod
#包括//std::string,std::to_string
使用名称空间std;
结构A
{
int x;
};
结构B
{
字符串s;
};
int main()
{
静态布尔常数a=is_pod::value;
静态断言(a,“啊…”);
静态断言(!is_pod::value,“Bah!”);
}

<>代码>结构> <代码>允许的是非POD,例如上面的代码> B>代码>,即为什么语言是这样设计的,这可能在Bjarne Stroustrup的《C++设计与演化》一书中找到。如果没有,那么可能只有比亚恩自己知道。由于 >结构> <代码>的C++通用性从一开始就存在。

我不会说编译器是在默认情况下这样做的。不应该。是的,我特别提到了std::is_pod。我的问题更像是“为什么它在默认情况下不这样做?”@barnes53:我不会说OP的语句有多大意义。没有任何情况下(语言规则要求)编译器断言PODness。那么“默认情况下”是什么呢"? 我看不出任何合理的解释。@grahamp:答案很简单:因为
#include <iostream>         // std::cout, std::endl
#include <type_traits>      // std::is_pod
#include <string>           // std::string, std::to_string
using namespace std;

struct A
{
    int x;
};

struct B
{
    string s;
};

int main()
{
    static bool const a = is_pod<A>::value;
    static_assert( a, "Ah..." );
    static_assert( !is_pod<B>::value, "Bah!" );
}