【问题标题】:'Cannot convert from _Ty2 to T*' error' with map'无法从 _Ty2 转换为 T*' 错误' 与地图
【发布时间】:2020-01-19 07:43:03
【问题描述】:

我想从 std::map 中返回一个元素作为指针,但我不断收到此错误并且找不到解决方法。

map的第二个元素是一个IService的指针,getService的返回是一个指向T的指针,它是一个IService,所以我不明白为什么会出现这个错误。

// Locator.h
template <class T>
class Locator
{
public:
    static T* getService(ServiceType serviceType);
    static void provide(ServiceType serviceType, T* service);

private:
    static std::unordered_map<ServiceType, IService*> _services;
};
// Locator.cpp
template <class T>
T* Locator<T>::getService(ServiceType serviceType)
{
    for (auto itr = _services.find(serviceType); itr != _services.end(); itr++)
    {
        return itr->second;
    }
}
//IService.h
class IService
{
public:
    virtual void start() = 0;
    virtual void stop() = 0;
    virtual void update() = 0;
};

【问题讨论】:

  • 请提供minimal reproducible exampleT 可能不是您想的那样。
  • 无关,但for 循环看起来奇怪。根本没有循环,你为什么要使用循环?
  • @molbdnilo 好吧,如果T 是从IService 派生的类,那它就说得通了。我认为这是这里尝试的,在这种情况下dynamic_cast&lt;T*&gt; 应该解决它。
  • 如果serviceType 不是_services 的键,getService 也有未定义的行为,我很确定编译器真的想警告你。
  • @MaxLanghof 我同意你的看法,所以我同意。

标签: c++ pointers interface


【解决方案1】:
  1. for 循环没有意义——第一个匹配项将中断它并返回。
  2. 返回值缺少强制转换——映射包含与返回类型 T* 无关的 IService 指针,除了 T* 是 IService 的基础(但看起来不像预期的那样)。如果 IService 是多态类型并且包含的​​映射元素支持转换为 T*,则动态转换可以解决它。

那就试试吧:

template <class T>
T* Locator<T>::getService(ServiceType serviceType)
{
  auto itr = _services.find(serviceType);
  return itr != _services.end() ? dynamic_cast<T*>(itr->second) : nullptr;
}

并且不要忘记为静态地图添加变量(在 cpp 中的某处):

std::unordered_map<ServiceType, IService*> Locator<ServiceImpl>::_services;

【讨论】:

  • 我没有得到关于静态地图变量的答案的第二部分。我为什么要那样做? ServiceImpl 应该是什么?感谢第一部分,动态演员解决了这个问题!但是现在我有一个链接错误,我认为它与您答案的第二部分有关
  • 你是对的......这需要更多的解释。静态函数只能访问静态成员.. 所以静态成员“_services”必须在 CPP 代码的某处为每个不同的类型 T 定义(否则链接器会报告“未解决的外部”错误。如果你使用 @ 987654323@ 和 T = ServiceImpl 您将需要 CPP 代码示例中给出的地图定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多