Что-то не так с поведением оператора преобразования в следующем коде:
struct A{
A(){};
A(const A &) = delete;
};
struct B : A{
B(const B & x){};
B(int x){};
};
struct C{
operator B() {
return B(1);
};
};
void foo(const A & x){
};
int main(){
C c;
foo(c.operator B()); //1) Ok
foo(c); //2) Not Ok
return 0;
};
Я получаю сообщение об ошибке 2):
test.cpp:24:7: error: use of deleted function 'A::A(const A&)'
foo(c); //2) Not Ok
^
Таким образом, вопрос: почему, черт возьми, он хочет скопировать-инициализировать A? Обратите внимание, B объявляет свой собственный конструктор копирования. Хотелось бы, чтобы этот вызов 1), который успешно, идентичен 2), но, по-видимому, это не так?
По практической проблеме, которую я пытаюсь решить: в классе C я хотел обеспечить преобразование в сторонний класс A, который запрещает копирование. Идея заключалась в том, чтобы вернуть прокси-сервер B: A, который бы добавил семантику перемещения поверх A. Может быть, есть другой способ определить оператор преобразования, чтобы получить A в стеке, соблюдая при этом свою политику не копирования.
В C ++ 98, когда константная ссылка инициализируется значением r, компилятору разрешается создавать временную копию значения r. Для этого может потребоваться наличие конструктора копирования.
Даже если вы не компилируете в режиме C ++ 98, сообщение об ошибке, которое вы наблюдаете, определенно выглядит как пережиток этого устаревшего требования. В вашем случае const A &
ссылка инициализируется значением r типа B
,
Код, похоже, хорошо компилируется с GCC (http://coliru.stacked-crooked.com/a/0d58fd31a0b50cf5), то есть то, что вы наблюдаете, скорее всего, ошибка в вашем компиляторе. Я просто предлагаю возможное обоснование этой ошибки.
gcc 6.1.1 компилирует показанный код без ошибок:
$ cat t.C
struct A{
A(){};
A(const A &) = delete;
};
struct B : A{
B(const B & x){};
B(int x){};
};
struct C{
operator B() {
return B(1);
};
};
void foo(const A & x){
};
int main(){
C c;
foo(c.operator B()); //1) Ok
foo(c); //2) Not Ok
return 0;
};
$ g++ -g -std=c++1z -o t t.C
$ g++ --version
g++ (GCC) 6.1.1 20160621 (Red Hat 6.1.1-3)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Я не вижу ничего плохого в показанном коде. Я считаю, что это ошибка любого компилятора, который вы используете.