83 votes

mise en page triviale vs standard vs POD

En termes simples, quelle est la différence entre les types triviaux, les types de mise en page standard et les POD ?

Plus précisément, je veux déterminer si new T est différent de new T() pour tout paramètre de modèle T . Lequel des traits de type is_trivial , is_standard_layout y is_pod devrais-je choisir ?

(En guise de question secondaire, l'un de ces traits de type peut-il être mis en œuvre sans la magie du compilateur) ?

3 votes

Je pense qu'il est un peu tard pour en parler. Mais pour les personnes qui cherchent une réponse détaillée et élaborée, voici le lien. Consultez la réponse de R Martinho Fernandes stackoverflow.com/questions/4178175/

74voto

Jerry Coffin Points 237758

Je ne pense pas que cela puisse être fait en termes vraiment profanes, du moins sans un lot d'explications supplémentaires. Un point important est l'initialisation statique par rapport à l'initialisation dynamique, mais expliquer cela à un profane serait plusieurs pages en soi...

Les PODs ont été (mal) définis dans C++98. Il s'agit en fait de deux intentions distinctes, qui ne sont pas très bien exprimées : 1) si vous compilez une déclaration de structure C en C++, ce que vous obtenez doit être équivalent à ce que vous aviez en C. 2) un POD n'aura jamais besoin/utilisera qu'une initialisation statique (et non dynamique).

C++0x/11 abandonne (presque) entièrement la désignation "POD" en faveur de "trivial" et "standard layout". La disposition standard est destinée à capturer la première intention - créer quelque chose avec une disposition identique à celle que vous obtiendriez en C. Trivial est destiné à capturer le support de l'initialisation statique.

Depuis new T vs. new T() traite de l'initialisation, vous probablement veulent is_trivial .

Je ne suis pas sûr que la magie du compilateur soit nécessaire. Ma réaction immédiate serait probablement oui, mais connaissant certaines des choses que les gens ont fait avec TMP, j'ai du mal à être certain que quelqu'un ne pourrait pas le faire aussi...

Edit : pour les exemples, il est peut-être préférable de simplement citer les exemples de N3290 :

struct N { // neither trivial nor standard-layout
   int i;
   int j;
    virtual ~N();
};

struct T { // trivial but not standard-layout
    int i;
private:
    int j;
};

struct SL { // standard-layout but not trivial
    int i;
    int j;
    ~SL();
};

struct POD { // both trivial and standard-layout
    int i;
    int j;
};

Comme vous pouvez sans doute le deviner, POD est également une structure POD.

1 votes

Il en va de même pour trivial + standard layout = POD toujours tenir ?

1 votes

@FredOverflow : oui, à condition que ce soit transitif, donc tous les membres (non statiques) doivent être triviaux+mise en page standard.

0 votes

@JerryCoffin il pourrait être utile de mentionner explicitement la disposition de la mémoire contiguë des types triviaux, car il s'agit d'une propriété assez importante.

8voto

Armen Tsirunyan Points 59548

Pour les types de POD new T() est une initialisation de valeur (qui initialisera la valeur de tous les membres) ,et new T n'initialisera pas les membres (initialisation par défaut). Pour les différences entre les différentes formes d'initialisation voir cette question . En résumé, vous devez is_pod .

1voto

JOSEPH BENOY Points 31

Mise en page est la façon dont les membres d'un objet de classe, de structure ou d'union sont disposés dans la mémoire. Très souvent, le langage spécifie la disposition, mais s'il y a quelque chose comme une fonction virtuelle, une classe de base virtuelle, etc, alors le compilateur est libre de choisir la disposition et celle-ci peut ne pas être contiguë. Cela conduit à plusieurs problèmes : nous ne pouvons pas sérialiser l'objet de manière appropriée ou le transmettre à des programmes écrits dans d'autres langages comme le C ou à des fonctions comme memcopy, car nous ne pouvons pas copier les données de manière fiable en nous assurant qu'elles ne sont pas dans des emplacements contigus.

Afin de permettre aux compilateurs et aux programmes c++ de supporter les opérations mentionnées ci-dessus, c++ a introduit 3 catégories pour les structures et les classes simples.

Trivial

Une classe ou une structure est triviale si elle respecte les règles :

  • pas de fonction virtuelle ou de classe de base virtuelle
  • pas de constructeur/opérateur/destructeur défini par l'utilisateur
  • la classe de base doit être triviale
  • tous les membres de la classe doivent être triviaux

Si une classe est triviale, sa disposition est contiguë mais il peut y avoir un remplissage en conséquence et le compilateur est libre de choisir l'ordre des membres dans la disposition. Nous pouvons avoir différents spécificateurs d'accès dans la même classe et si nous utilisons un constructeur paramétré, nous devons évidemment spécifier le constructeur par défaut. Mais si vous voulez garder la classe triviale alors vous devriez explicitement faire le constructeur par défaut.les constructeurs devraient être publics.

Modèle standard

  • Pas de fonctions virtuelles et de classe de base virtuelle
  • Tous les membres non statiques doivent avoir les mêmes spécificateurs d'accès.
  • Tous les éléments non statiques doivent avoir une disposition standard.
  • Toutes les classes de base doivent avoir une présentation standard
  • Tous les membres de la classe de base doivent être statiques.
  • Le type de la classe de base et du premier membre non statique de la classe ne doit pas être le même.

La mise en page standard est bien définie et elle peut être mémorisée de manière fiable et transmise aux programmes C de manière appropriée. Les fonctions de mise en page standard peuvent également avoir des fonctions spéciales définies par l'utilisateur comme le constructeur et le destructeur.

POD (Plain old data)

Si une classe ou une structure est à la fois triviale et standard, on dit qu'elle est POD. Chaque membre est stocké dans l'ordre spécifié lors de la déclaration de l'objet. Les classes POD doivent avoir des membres de données non statiques POD. Les classes POD peuvent être copiées ou transmises à des programmes C de manière fiable.

Programme C++ avec une classe qui est triviale, à disposition standard et donc POD.

#include<iostream>
#include<type_traits>
class xyz
{
public:
    int a;
    int b;
    xyz() = default;
    xyz(int x, int y) :a(x), b(y) {}
};
int main() {
    std::cout << std::is_trivial<xyz>() << std::endl;//true
    std::cout << std::is_standard_layout<xyz>() << std::endl;//true
    std::cout << std::is_pod<xyz>() << std::endl;//true
}

Types littéraux

Pour un type littéral, la disposition peut être déterminée au moment de la compilation. Des exemples de types littéraux sont void, des types scalaires tels que int, float, etc, des références, des tableaux de void, de types scalaires ou de références et une classe qui a un destructeur trivial et un ou plusieurs constructeurs constexpr qui ne sont pas des constructeurs move ou copy. ne sont pas des constructeurs de déplacement ou de copie. En outre, tous ses membres de données non statiques et ses classes de base doivent être de type littéral et non volatile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X