Страницы

Поиск по вопросам

четверг, 9 января 2020 г.

Ошибка компиляции при виртуальном наследовании с использованием multi_index_container

#cpp #ооп #boost


#include 
#include 
#include 

namespace mi = boost::multi_index;


namespace vo {

class Statable {};

class Entity : virtual public Statable {};

} /* namespace vo */

class Statable : virtual public vo::Statable {};

class Entity
    : virtual public vo::Entity
    , public Statable
{
    std::string name_;

public:
    std::string const& name() const { return name_; }

private:
    typedef mi::multi_index_container <
      Entity*
    , mi::indexed_by > >
    > nested_objects_t;

    nested_objects_t nested_objects_;
};


Добрый день!
При такой архитектуре кода (это упрощенный пример, естественно), ломается компиляция
с ошибкой:


  Error C1001   An internal error has occurred in the compiler


Методом проб и ошибок выявлено, что проблема в строке:

mi::hashed_unique >


Данная проблема возникает только тогда, когда присутствует виртуальное наследование!
Т.е. если теперь Entity сделать только наследником от ::Statable (убрать virtual public
vo::Entity), а того в свою очередь сделать обычным наследником от vo::Statable (без
virtual public), то ошибка пропадет.

Также ошибка пропадет если просто вынести typedef за пределы класса Entity!

Почему это происходит, я не могу понять никак?

P.S.
Пробовал в VS2010, VS2012, VS2015 с различными версиями boost от 1.33 до 1.68
    


Ответы

Ответ 1



У меня эта ошибка воспроизвелась даже в более простом примере. Достаточно наличия виртуального наследования в верхнем классе Entity для ее возникновения. Базового класса достаточно одного, любого. Однако после добавления #pragma pointers_to_members(full_generality) ошибка исчезла. Я не проверял, приводит ли это к полноценной функциональности вашего кода, однако при работе с указателями на члены класса в условиях множественного и виртуального наследования в MSVC++ я бы рекомендовал всегда выставлять эти опции в наиболее "безопасный" вариант.

Ответ 2



Как альтернативный вариант - добавить опцию компилятора /vmg, переключающую режим генерации указателей на члены классов в обобщенный режим.

Комментариев нет:

Отправить комментарий