首页 > 解决方案 > 从 'shared_ptr 没有可行的转换' 到 'shared_ptr'

问题描述

我试图理解在尝试实现访问者模式以进行验证时看到的错误。当我从构建目录执行 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 的前向声明以避免循环包含。

IE

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

非常感谢任何帮助

标签: c++11c++17visitor-pattern

解决方案


推荐阅读