我正在尝试理解为实现验证目的而实施Visitor模式时看到的错误。当我从构建目录执行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”类,这是我要验证的元素。该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)中,我正在使用对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中发现了许多关于此的文章,但所有这些文章主要是关于不同类型的,例如bool和string之类的东西。
喜欢这个 no viable conversion from 'int' to 'Time'
No viable conversion from 'bool' to 'std::string'
我确实理解上面提到的文章,但是就我而言,编译器看到的是相同的类型,只是名称空间不同,即'shared_ptr'与'shared_ptr'如何告诉编译器那些是相同的对象?当同一类(即“ IdInterface”)相同时,为什么编译器会看到不同的命名空间。在上面的某些文章中,已经提到如果未定义该类,则可以看到此错误,但是由于这个原因,我明确地使用fotrward声明。
我将整个3个类和3个接口放在github上以显示完整图片。 https://github.com/courteous/visitor/tree/master/src
我们非常感谢您的帮助