Вы можете обойти это, имея явный класс HugoCopy
, подобный следующему
class HugoCopy;
class Hugo {
public:
Hugo() { ... }
Hugo(HugoCopy const&);
explicit Hugo(Hugo const&) { ... }
};
struct HugoCopy {
HugoCopy(Hugo const& hugo)
:hugo(hugo)
{ }
Hugo const& hugo;
};
Hugo::Hugo(HugoCopy const&) { ... }
Теперь применяется следующая семантика
Hugo a;
Hugo b = a; // forbidden
Hugo c(a); // allowed
Hugo d = HugoCopy(a); // allowed
Hugo f() {
Hugo a;
return a; // forbidden
return HugoCopy(a); // allowed
}
В качестве альтернативы вы можете использовать функцию преобразования
class Hugo {
public:
Hugo() { ... }
explicit Hugo(Hugo const&) { ... }
};
struct HugoCopy {
HugoCopy(Hugo const& hugo)
:hugo(hugo)
{ }
operator Hugo const&() { return hugo; }
private:
Hugo const& hugo;
};
Это опирается на тонкий угол языка C ++.Поэтому, если вы используете это, вам лучше знать, что вы делаете, или не делаете этого: сначала он вызывает функцию преобразования в HugoCopy (или, в первом случае, в конструкторе Hugo
), чтобы получить Hugo
/ Hugo const&
, а затем direct инициализирует целевой Hugo
объект с этим Hugo
объектом.GCC не нравится код, но Clang и Comeau / EDG принимают его в соответствии с вышеуказанной семантикой.