【问题标题】:Converting shared_ptr to shared_ptr of same type in different namespace将 shared_ptr 转换为不同命名空间中相同类型的 shared_ptr
【发布时间】:2015-12-26 11:57:33
【问题描述】:

我有这个Foo class,其中包含shared_ptrHotel class,以及对Rules class 的引用(在namespace Rules 内):

class Foo
{
public:
   //...
   void doStuff();
private:
   std::shared_ptr<Hotel> mHotelClicked;
   Rules::IRules& mRules;
}

doStuff() 方法的实现方式如下:

void Foo::doStuff()
{
   //...
   std::shared_ptr<Hotel> p = hotel;

   //Here I need to pass both smart pointers
   if(mRules.isValidMove(mHotelClicked,p) == true) //ERROR here! See bellow.
   {
       //...
   }
}

Rules 位于名为Rulesnamespace 中,在以下界面中:

namespace Rules
{
  class IRules
  {
  public:
    virtual bool isValidMove(std::shared_ptr<Hotel> hotel1, std::shared_ptr<Hotel> hotel2) = 0;
    //...
  };
}

错误:

error C2664: 'Rules::IRules::isValidMove' : cannot convert parameter 1 from 'std::shared_ptr<_Ty>' to 'std::shared_ptr<_Ty>'

当我将鼠标悬停在:

mRules.isValidMove(mHotelClicked,p)

我看到以下错误

No suitable user-defined conversion from "std::shared_ptr<Hotel>" to "std::shared_ptr<Rules::Hotel>" exits.

注意Rules::(可能是因为它来自命名空间)。

我的两个问题:

  • [1]如何解决此错误?由于两个参数是相同的类型?两者都是指向 Hotel 类的智能指针。

  • [2] 这样做的最佳做法是什么?我应该通过引用传递吗?

【问题讨论】:

  • 您是否有两个相同的类,称为 Hotel,定义在不同的命名空间中?如果是这样,很难找到理由。
  • 不,Hotel 类只定义一次,并且没有任何命名空间。只有 Rules 类有自己的命名空间。
  • 哦。那么抱歉——我担心这个问题超出了我的想象。
  • 编译器认为您在命名空间Rules 中确实有一个Hotel 的定义,并且在全局命名空间中也有一个。意识到::HotelRules::Hotel 是两个截然不同的、完全不相关的类。您是否有机会从namespace Rules {} 内部#include "Hotel.h" 或类似的东西?如果是这样,请停止并停止。
  • 除了@IgorTandetnik 的建议,你能检查一下你是否在命名空间Rules 中转发Hotel 的声明

标签: c++ c++11 shared-ptr smart-pointers


【解决方案1】:

必须发生的事情是 Rules 命名空间中的某处有 Hotel 类的错误声明,所以

virtual bool isValidMove(std::shared_ptr<Hotel> hotel1, std::shared_ptr<Hotel> hotel2) = 0;

真正编译为

virtual bool isValidMove(std::shared_ptr<Rules::Hotel> hotel1, std::shared_ptr<Rules::Hotel> hotel2) = 0;

而不是对全局命名空间中的Hotel 类的引用。

当对命名空间内的类进行非限定引用时,编译器首先检查该命名空间内是否存在该类,然后检查全局命名空间(这有点简化,还有一些其他规则,但除此之外点)。

我猜Rules::Hotel 的声明(位于您未显示的头文件中的某处)是错误的。您需要找到它,并通过在 Rules 命名空间之外声明它来修复它。

如果您确实有不同的 Rules::Hotel 类(假设您有充分的理由),您可以将上述声明更改为:

virtual bool isValidMove(std::shared_ptr<::Hotel> hotel1, std::shared_ptr<::Hotel> hotel2) = 0;

为了强制它引用全局命名空间中的Hotel 类。丑,但 C++ 不是选美比赛。

【讨论】:

  • 谢谢大家! Hotel 类确实是在规则命名空间内的前向声明! :) 谢谢!!
猜你喜欢
  • 1970-01-01
  • 2012-07-22
  • 2015-05-08
  • 2016-08-08
  • 2014-03-31
  • 1970-01-01
  • 2012-07-31
  • 2017-08-06
  • 2010-11-24
相关资源
最近更新 更多