Я собираюсь создать иерархию классов исключений, которая концептуально выглядит примерно так:
#include <iostream>
#include <stdexcept>
class ExceptionBase : public std::runtime_error {
public:
ExceptionBase( const char * msg ) : std::runtime_error(msg) {}
};
class OperationFailure : virtual public ExceptionBase {
public:
using ExceptionBase::ExceptionBase;
};
class FileDoesNotExistError : virtual public ExceptionBase {
public:
using ExceptionBase::ExceptionBase;
};
class OperationFailedBecauseFileDoesNotExistError
: public OperationFailure, FileDoesNotExistError {
public:
using ExceptionBase::ExceptionBase; // does not compile
};
int main() {
OperationFailedBecauseFileDoesNotExistError e("Hello world!\n");
std::cout << e.what();
}
Все конструкторы должны выглядеть так же, как конструктор класса ExceptionBase
. Производные исключения отличаются только своим типом, в противном случае нет никакой дополнительной функциональности. Последний тип исключения, упомянутый в приведенном выше коде, также должен иметь эти конструкторы. Возможно ли это с помощью функции наследования конструкторов стандарта С++ 11? Если это невозможно: каковы альтернативы?
(Кстати: в приведенном выше коде классы OperationFailure
и FileDoesNotExistError
компилировались не с gcc 4.8, а с clang 3.4. Судя по всему, gcc отвергает наследование конструкторов для виртуальных баз. Было бы интересно узнать, кто здесь прав. Оба компилятора отвергли класс OperationFailedBecauseFileDoesNotExistError
, потому что наследующий конструктор не наследуется от прямой базы.)
using OperationFailure::OperationFailure
? Но, вероятно, это не сработает из-за двойного наследования. - person Albert   schedule 16.10.2013OperationFailure
при создании объекта (с параметризованным ctor). При замене виртуального наследования на не виртуальное оно работает. Я предлагаю вам отправить отчет об ошибке для gcc, так как я не могу найти ничего в Стандарте, что запрещает это, и последнее предложение N2540 явно разрешает это. - person dyp   schedule 16.10.2013