假设我有一个奇怪的字符串类型,它拥有或不拥有它的底层缓冲区:
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 中是保证的)。薛定谔的所有权模型表明这个复制构造函数本身就是未定义的行为。
是吗?
一个更具说明性的例子可能是:
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
可能比getX()
. 标准对此有任何说明吗?