基になるバッファーを所有しているか所有していない、奇妙な文字列型があるとします。
class WeirdString {
private:
char* buffer;
size_t length;
size_t capacity;
bool owns;
public:
// Non-owning constructor
WeirdString(char* buffer, size_t length, size_t capacity)
: buffer(buffer), length(length), capacity(capacity), owns(false)
{ }
// Make an owning copy
WeirdString(WeirdString const& rhs)
: buffer(new char[rhs.capacity])
, length(rhs.length)
, capacity(rhs.capacity)
, owns(true)
{
memcpy(buffer, rhs.buffer, length);
}
~WeirdString() {
if (owns) delete [] buffer;
}
};
そのコピーコンストラクターはどこかで標準に違反していますか? 検討:
WeirdString get(); // this returns non-owning string
const auto s = WeirdString(get());
s
追加のコピー コンストラクターが省略されたかどうかに応じて、所有または非所有のいずれかになります。これは、C++14 以前では許可されていましたが、省略可能です (C++17 では保証されています)。Schrödinger の所有権モデルは、このコピー コンストラクター自体が未定義の動作であることを示唆しています。
それは...ですか?
より具体的な例は次のとおりです。
struct X {
int i;
X(int i)
: i(i)
{ }
X(X const& rhs)
: i(rhs.i + 1)
{ } ~~~~
};
X getX();
const auto x = X(getX());
どのコピーが省略されるかに応じて、x.i
で返されたものよりも 0、1、または 2 増える可能性がありますgetX()
。規格はこれについて何か言っていますか?