У меня есть класс (, назовем его base
на данный момент ), который имеет защищенный интерфейс, включая защищенные конструкторы и т. д. Некоторые функции base
возвращают экземпляр base
по значению:
class base {
protected:
base() {}
base (base const &other) {} // line 6
base foo () {
base ret;
return ret;
}
};
Эти функции заключены в производные классы, чтобы возвращать производный тип следующим образом:
class derived : public base {
private:
derived(base const &b) : base(b) {}
public:
derived() : base() {}
derived foo() {
derived d(base::foo()); // line 21
return d;
}
};
Чтобы упростить преобразование возвращаемого типа base
в возвращаемый тип derived
, я предоставляю закрытый конструктор в derived
, который обрабатывает это.
Компиляция этого на Centos 5.8 с gcc 4.1.2 приводит к следующей ошибке:
test.cpp: In member function ‘derived derived::foo()’:
test.cpp:6: error: ‘base::base(const base&)’ is protected
test.cpp:21: error: within this context
С gcc 4.6.1 и clang 2.9 в Linux Mint 12 код компилирует файл даже с -Wall -Wextra
, за исключением предупреждения unused parameter
для конструктора копирования base
.
Я думаю, что это может быть ошибка компилятора в gcc 4.1.2, но мне не удалось ничего найти в сети. Кто-нибудь видел это раньше?
Я не могу обновить компилятор без сильной боли. Есть ли простой обходной путь, кроме как сделать конструктор копии базового класса общедоступным?
РЕДАКТИРОВАТЬ Я добавил base b;
перед строкой 21 в derived::foo()
. В этом случае gcc 4.6.1 и gcc 4.1.2 жалуются, что ctor по умолчанию base
защищен, clang 2.9 компилируется без предупреждения. Это то, что сказал Дэвид Родригес -dribeas в своем комментарии -ctor по умолчанию не может быть вызван для другого экземпляра base
.
РЕДАКТИРОВАТЬ 2 Стандартный абзац, который здесь применим, — 11.5 [class.protected]. gcc 4.1.2 кажется правильным, отклонив мой код как неправильный, и мне интересно, почему gcc 4.6.1 и clang разрешают это. Смотрите мой собственный ответ для предварительного решения.