Warum kann std :: tupleint nicht trivial kopierbar sein?

8

Gebaut mit diesem Online-Compiler , dem folgenden Code:

%Vor%

Ausgänge:

%Vor%

Ich erhalte die gleichen Ergebnisse mit Visual Studio 2015.

Warum ist das der Fall? Gibt es einen triftigen Grund, warum ein std::tuple von POD-Typen, geschweige denn ein einfacher std::pair , nicht einfach kopierbar sein könnte? Ich nehme an, dass ihre Implementierungen einige benutzerdefinierte Zuweisungsoperatoren bereitstellen, aber wie würden sie sich von den Standardversionen unterscheiden, die vom Compiler generiert werden?

    
Patryk Czachurski 05.08.2016, 02:00
quelle

2 Antworten

7

Das Problem, das pair nach oben bringt, was die triviale Kopierbarkeit betrifft, ist, dass der Standard nicht erfordert, dass die Kopier / Verschiebe-Zuweisungsoperatoren trivial sind. Der Standard deklariert explizit, dass die Kopien- / Verschiebungs -Konstrukteure vordefiniert sind, nicht jedoch für die Zuweisungen. Eine Implementierung könnte sie ebenfalls als Standard verwenden, aber der Standard erfordert dies nicht.

Es gibt keinen wirklich guten Grund, warum der Standard dies nicht erfordert. Aber das tut es nicht.

Für tuple sind die Dinge ein viel komplizierter. Viele tuple -Implementierungen basieren auf einem Speicherpuffer der richtigen Größe / Ausrichtung und verwenden das Placement new , um die einzelnen Mitglieder innerhalb dieses Puffers zu konstruieren. Das ist alles in Ordnung und gut, aber ein solcher Typ muss einen manuellen Kopier- / Verschiebungskonstruktor implementieren, da er den Kopier- / Verschiebungskonstruktor jedes Typs aufrufen muss. Selbst wenn es wüsste, dass sie alle nur kopierbar sind und sie über memcpy kopiert haben, ist das immer noch eine manuelle Operation. Und das disqualifiziert es von der Trivialkopierbarkeit.

Nun gibt es Implementierungen von tuple , die trivial kopierbar sein könnten, wenn die Typen trivial kopierbar sind. Aber es gibt keine Notwendigkeit, sie auf diese Weise umzusetzen. Und es würde die Implementierung von tuple enorm erschweren, dass sie sich selbst implementieren müssen, wenn alle Typen trivial kopierbar sind, und sie auf andere Weise implementieren.

    
Nicol Bolas 05.08.2016, 02:31
quelle
6

Da std::tuple über copy / move ctor- und Zuweisungsoperatoren verfügt, ist die Klasse nicht-trivial kopierbar.

Siehe cpp-Referenz :

  

Eine trivial kopierbare Klasse ist eine Klasse, die

%Vor%

Aber std::tuple hat alle oben genannten Konstruktoren und Zuweisungsoperatoren.

    
Mine 05.08.2016 02:12
quelle