Ошибка лягушки: доступ члена к неполному типу - PullRequest
1 голос
/ 02 ноября 2019

У меня очень простое созвездие из двух классов "Id" и "IdValidator" и их соответствующих интерфейсов. Купленные классы зависят друг от друга, то есть существует круговая зависимость между купленными из них. Проблема с циклической зависимостью решается с помощью предварительного объявления. Это все прекрасно компилируется и связывается с clang, т.е. git commit: e4d4edafa924fad8902c52a10a2c0ebbd39907bf из master master

Затем я пришел к необходимости разделить эти два класса в разных пространствах имен. Все, что я сделал, не изменив рабочую версию, я создал две директории и поместил соответствующий класс и его interfaecs во второй каталог. Измененные пространства имен и соответствующие им элементы включают.

Я могу выполнить «cmake ../», но когда я запускаю «make», я сталкиваюсь со следующей ошибкой:

, когда я сейчасскомпилируйте предыдущий рабочий пример, я получаю сообщение об ошибке

visitor/validator/IdValidator.cpp:36:23: error: member access into incomplete type 'std::__shared_ptr_access<IdInterface, __gnu_cxx::_S_atomic, false, false>::element_type'
      (aka 'IdInterface')
                string name = entity->getName();
                                    ^
visitor/validator/IdValidatorInterface.h:12:7: note: forward declaration of 'IdInterface'
class IdInterface;

здесь 4 файла нерабочей версии находятся в разделенной ветке, т.е. commit 58345716e9b4a6062a470519690502b5fb80662a

здесьрассматриваемые файлы:

IdValidator.h

#ifndef _ID_VALIDATOR_
#define _ID_VALIDATOR_

#include <string>
#include <vector>
#include <limits>
#include <memory>
#include "../src/Id.h"
#include "IdValidatorInterface.h"

namespace validator
    {

    using Id = src::Id;
    using IdValidatorInterface = src::IdValidatorInterface;


    class IdValidator : public virtual IdValidatorInterface
        {

    public:

        IdValidator();
        virtual ~IdValidator();

        virtual bool isValid( shared_ptr<IdInterface> entity) override;

        vector<string> validate(shared_ptr<IdInterface> entity) override;

        };

    }


#endif

IdValidator.cpp

#include "IdValidator.h"
#include "../src/Id.h"
#include "../src/IdInterface.h"

using namespace std;

namespace validator
    {

    using Id = src::Id;

    IdValidator::IdValidator()
        {
        }

    bool IdValidator::isValid(shared_ptr<IdInterface> entity)
        {

        vector<string> listOfErros = validate(entity);

        if(listOfErros.empty() ){
            return false;
        }else{
            return true;
        }

        }

    vector<string> IdValidator::validate(shared_ptr<IdInterface> entity)
        {


        vector<string> stringList = vector<string>();

        // do some validation of the name
        string name = entity->getName();

        if (name == "BadName")
            {
            string error = "Error. id name is bad";
            stringList.push_back(error);
            return stringList;
            }

        return stringList;

        }
    }

IdValidatorInterface.h

#ifndef _ID_VALIDATOR_INTERFACE_
#define _ID_VALIDATOR_INTERFACE_

#include "BaseElementValidatorInterface.h"
#include <string>
#include <memory>
#include <vector>


using namespace std;

class IdInterface;

namespace validator
    {


    class IdValidatorInterface : public virtual BaseElementValidatorInterface
        {

     public:
         IdValidatorInterface();
         virtual ~IdValidatorInterface();

         virtual bool isValid( shared_ptr<IdInterface> entity )  = 0;
         virtual vector<string> validate( shared_ptr<IdInterface> entity) = 0;

        };

    }

#endif

Компилятор в основномжалуется на предварительную декларацию "class IdInterface;"в заголовочном файле IdValidatorInterface.h. Я не уверен, как решить эту проблему, поэтому прошу помощи здесь. Другие статьи предлагают включить рассматриваемый файл, но это не помогает в этой ситуации, например,

доступ к элементу в неполном типе 'QScrollBar'

Доступ к члену внеполный тип 'CALayer'

Это выполнимо в c ++ или они должны находиться в одном и том же пространстве имен и той же папке, чтобы это работало. Я действительно хотел бы разделить эти два.

Я использую Clang версии 6.0.1 (emscripten 1.38.12: 1.38.12) Цель: x86_64-unknown-linux-gnu Модель потока: posix

1 Ответ

1 голос
/ 02 ноября 2019

Похоже, вы ожидаете объявить IdInterface в области видимости файла. Глядя на ваше связанное репозиторий github , IdInterface определяется в пространстве имен src. src::IdInterface != ::IdInterface Вы заранее объявили тип, который никогда не определяется.

Обновите свое предварительное объявление, чтобы оно было в namespace src, и оно, вероятно, решит вашу проблему.

namespace src{
    class IdInterface;
}
namespace validator
{


class IdValidatorInterface : public virtual BaseElementValidatorInterface
    {

 public:
     IdValidatorInterface();
     virtual ~IdValidatorInterface();

     virtual bool isValid( shared_ptr<src::IdInterface> entity )  = 0;
     virtual vector<string> validate( shared_ptr<src::IdInterface> entity) = 0;

    };

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