Вы, вероятно, думаете об этом Руководстве по Boost.Exception , которое я напишу здесь для полноты:
Использование виртуального наследования в типах исключений
Типы исключений должны использовать виртуальное наследование при наследовании от других типов исключений.Это понимание связано с Эндрю Кениг.Использование виртуального наследования предотвращает проблемы неоднозначности в обработчике исключений:
#include <iostream>
struct my_exc1 : std::exception { char const* what() const throw(); };
struct my_exc2 : std::exception { char const* what() const throw(); };
struct your_exc3 : my_exc1, my_exc2 {};
int
main()
{
try { throw your_exc3(); }
catch(std::exception const& e) {}
catch(...) { std::cout << "whoops!" << std::endl; }
}
Программа, приведенная выше, выдает «whoops!»потому что преобразование в std :: exception является неоднозначным.
Издержки, вносимые виртуальным наследованием, всегда незначительны в контексте обработки исключений.Обратите внимание, что виртуальные базы инициализируются непосредственно конструктором самого производного типа (тип, переданный в оператор throw, в случае исключений.) Однако, как правило, эта деталь не имеет значения, когда boost :: exception используется, потому что позволяет типам исключений быть тривиальными структурами без элементов (инициализировать нечего). См. Типы исключений как простые семантические теги .