GCC: инициализация встроенного объекта C ++ 11 (с использованием «this») не работает при наличии виртуального наследования в иерархии - PullRequest
4 голосов
/ 21 марта 2019

C ++ 11 встроенная инициализация объекта не работает (в GCC), когда этот указатель используется при инициализации и существует виртуальное наследование в иерархии.Может ли это быть ошибка GCC (потому что он работает в CLang)?Или пробел в самом стандарте C ++ 11?

Пример (можно попробовать в здесь ), когда приведенный ниже код скомпилирован с GCC:

FieldIndex m_inB{"inB", this};

не исполняется.Но он выполняется при компиляции с CLang.

РАБОЧАЯ РАБОТА: Получите A из FieldIndexContainer как виртуальный

#include <string.h>
#include <iostream>
#include <list>
using namespace std;

class FieldIndexContainer
{
public:
    class FieldIndex
    {
    public:
        FieldIndex( const std::string& fieldName, FieldIndexContainer* owner) 
        {
            cout << "FieldIndex called = " << fieldName << endl;
        }
    };  
};

class A : public FieldIndexContainer
{
public:
    FieldIndex m_inA{ "inA", this};
};

class Mid : virtual public A {};

class B : virtual public Mid
{
public:     
    FieldIndex m_inB{"inB", this};
};

int main () 
{
    B* b = new B;
    return 0;
}

Ответы [ 2 ]

1 голос
/ 21 марта 2019

GCC не может вызвать конструктор члена m_inB. В C ++ нет возможного случая, когда объект успешно создан, но один из его членов не является.

Это ошибка в GCC.

1 голос
/ 21 марта 2019

Ваш MCVE может быть дополнительно уменьшен.

Нет необходимости в class Mid.class B может быть virtual public унаследовано от class A, и проблема все еще существует.

Помимо предложенного вами обходного путиполучения A из FieldIndexContainer как virtual, код также работает корректно без какого-либо virtual наследования вообще .

См. Демонстрация в реальном времени 1 .

При инициализации элемента код работает правильно, без каких-либо обходных путей.

См. Live Demo 2 .

Итак, это ошибка GCC.

Был выдан отчет об ошибке для GCC под названием: Отсутствует инициализация по умолчанию для члена в сочетании с виртуальным наследованием , что очень похоже на то, что вы наблюдаете с вашим кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...