folgendes Programm vor:Rückkehr Provisorien vom Typ mit gelöscht verschieben/kopieren ctor
#include<iostream>
using namespace std;
struct S
{
S() = default;
S(const S& other) = delete;
S(S&& other) = delete;
int i;
};
S nakedBrace()
{
return {}; // no S constructed here?
}
S typedBrace()
{
return S{};
}
int main()
{
// produce an observable effect.
cout << nakedBrace().i << endl; // ok
cout << typedBrace().i << endl; // error: deleted move ctor
}
Beispielsitzung:
$ g++ -Wall -std=c++14 -o no-copy-ctor no-copy-ctor.cpp
no-copy-ctor.cpp: In function 'S typedBrace()':
no-copy-ctor.cpp:19:12: error: use of deleted function 'S::S(S&&)'
return S{};
^
no-copy-ctor.cpp:8:5: note: declared here
S(S&& other) = delete;
Es erstaunt mich, dass gcc nakedBrace()
akzeptiert. Ich dachte, dass die beiden Funktionen konzeptionell gleichwertig sind: Eine temporäre S
wird konstruiert und zurückgegeben. Kopieren Elision kann oder darf nicht durchgeführt werden, aber die Verschiebung oder Kopie ctor (beide sind hier gelöscht) muss immer noch zugänglich sein, wie von der Norm (12.8/32) vorgeschrieben.
Bedeutet das, dass nakedBrace()
niemals ein S konstruiert? Oder doch, aber direkt im Rückgabewert mit Klammerinitialisierung, so dass konzeptuell keine Kopie move/ctor benötigt wird?