Ответ 1
Всякий раз, когда виртуальное наследование вовлечено.
Пример:
struct A {
int a;
A (int a) : a(a) {}
};
struct B: virtual A {
B() : A(0) {}
};
B makeB { return B(); }
struct C : B {
C() : B(makeB()), A(42) {}
};
Конструктор C
инициализирует подобъект A
, поэтому конструктор B
не может. Как бы makeB
узнал, должен ли он инициализировать A
?
Удаление копии все еще теоретически возможно в этом случае. Реализация должна была бы прозрачно создать две двоичные версии makeB
или добавить невидимый аргумент для makeB
(т. makeB
Использовать технику, применяемую для самих конструкторов), чтобы она могла создать B
с инициализацией A
или без нее. Однако это может потребовать несовместимых изменений в ABI.
Там может быть или не быть дефект в стандарте. Эта ситуация, вероятно, не была предусмотрена комитетом. Если бы это было так, я был бы рад прочитать обсуждение, так как оно, несомненно, оставило бумажный след. Так что намерение неясно, пока нет разъяснений от комитета. Если намерение состоит в том, чтобы в этом случае исключить возможность копирования, проклятие несовместимости ABI может потребовать дальнейших изменений в стандарте (если только комитет не предвидел ситуацию и не удостоверился, что все совместимо с ней, и в этом случае должны быть некоторые опять бумажный след).