Я пытаюсь понять ошибку, которую вижу при попытке реализовать шаблон посетителя для проверки. Когда я выполняю cmake ../ из каталога сборки, я получаю следующую ошибку:
validator/src/Id.cpp:30:38: error: no viable conversion from 'shared_ptr<src::IdInterface>' to 'shared_ptr<IdInterface>'
bool isValid = validator->isValid( castedObj );
/home/tito/Projects/validator/src/IdValidatorInterface.h:24:50: note: passing argument to parameter 'entity' here
virtual bool isValid( shared_ptr<IdInterface> entity ) = 0;
Мне удалось воспроизвести ошибку с простыми 3 классами. Для примера я поместил их вто же пространство имен. Эти классы являются "Id" классом, это элемент, который я хотел бы проверить. Идентификатор наследуется от BasePrimitive. Единственная цель класса BasePrimitive - получить возможность проверки сущности указателя общего ресурса, поскольку класс BasePrimitive наследуется от
"enable_shared_from_this". т. е. код ниже
#include "Id.h"
#include "IdInterface.h"
#include "IdValidatorInterface.h"
#include <iostream>
using namespace std;
namespace src
{
const string Id::name = "ID";
Id::Id()
{
}
Id::~Id()
{
}
bool Id::validate(shared_ptr<IdValidatorInterface> validator)
{
shared_ptr<Id> thisObj = shared_from_this();
shared_ptr<IdInterface> castedObj = static_pointer_cast<IdInterface>(thisObj);
bool isValid = validator->isValid( castedObj );
if (!isValid)
{
vector<string> vectorOfErrors = validator->validate(castedObj );
std::cout << " the Id has NOT been validated" << std::endl;
} else
{
std::cout << " the Id has been validated" << std::endl;
}
return isValid;
}
string Id::getName() const {
return Id::name;
}
}
часть, где код нарушен, это: Здесь я получаю share_ptr из этого класса, а затем делаю случай статического указателя. Это работает хорошо, но когда я пытаюсь передать его методу isValid, он ломается.
shared_ptr<Id> thisObj = shared_from_this();
shared_ptr<IdInterface> castedObj = static_pointer_cast<IdInterface>(thisObj);
bool isValid = validator->isValid( castedObj );
и класс BasePrimitive
namespace src {
class BasePrimitive: public enable_shared_from_this<BasePrimitive> {
public:
~BasePrimitive();
BasePrimitive();
};
}
Тогда у меня есть свой класс валидатора, т.е. IdValidator
#include "IdValidator.h"
#include "Id.h"
#include "IdInterface.h"
using namespace std;
namespace src
{
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;
}
}
И у меня есть еще 3 интерфейса: BaseElementValidatorInterface, IdValidatableInterface, IdValidatorInterface, которые существуют просто для явного указания, что это чисто виртуальные функции.
в последнем интерфейсе, т.е. IdValidatorInterface iЯ использую предварительное объявление IdInterface, чтобы избежать циклических включений.
т.е.
class IdInterface;
Первая проблема: «нет жизнеспособного преобразования из« shared_ptr »в« shared_ptr »»
единственное отличие, которое я вижу здесь, это полное квалифицированное пространство имен,Я хотел бы понять природу, то есть происхождение этой ошибки. Связано ли это с скомпилированными определениями, которые я передаю clang, например
add_definitions(" -pedantic -pedantic-errors -W ")
add_definitions(" -Wall -Wextra -Werror -Wshadow -Wnon-virtual-dtor ")
add_definitions(" -v ")
или с чем-то еще.
Я нашел несколько статей в stackoverflow об этом, но все они были в основном о разных типахт.е. что-то вроде bools и string.
как этот нет жизнеспособного преобразования из 'int' во 'время'
нет жизнеспособного преобразования из 'bool' в'std :: string'
Я понимаю статьи, упомянутые выше, но в моем случае компилятор видит один и тот же тип, за исключением того, что пространство имен отличается, например, от 'shared_ptr' до 'shared_ptr' каксказать компилятору, что это одни и те же объекты? Почему компилятор видит разные пространства имен, когда это один и тот же класс, т.е. "IdInterface". В некоторых из приведенных выше статей упоминалось, что эту ошибку можно увидеть, если класс не определен, но по этой причине я использую явное объявление fotrward.
Я поместил все эти 3 класса и 3 интерфейса на github, чтобы показать полную картину. https://github.com/courteous/visitor/tree/master/src
Любая помощь высоко ценится