编译错误:"没有匹配函数来调用"返回static_cast引用时

时间:2016-12-15 01:10:52

标签: c++ c++11 compiler-errors g++ static-cast

我对这个模板化方法有这个编译错误no matching function for call to ‘Color::Color(Component&)’

template<typename U>
inline U& getObject(const std::string& key)
  {
    return (static_cast<U>(*(_map.at(key))));
  }

我这样称呼(组件是我的类型包含我的地图):

components.getObject<Color>("Color").getColor();

颜色继承自组件 _map 是字符串和组件* 的映射(组件上的指针)。

我有很多从Component派生的类型,我在地图中存储了一个指向它们的指针。但是当我尝试从地图中获取一个Component并将其转换为特定类型以使用它时,我得到了上面的编译错误。我不明白为什么。

1 个答案:

答案 0 :(得分:2)

  

我有很多从Component派生的类型,我在地图中存储了一个指向它们的指针。但是当我尝试从地图中获取一个Component并将其转换为特定类型以使用它时,我得到了上面的编译错误。我不明白为什么。

因为您的功能编码错误。

您的函数正在从地图中检索O(N)指针,取消引用指针以仅访问对象的Component*部分(而不是完整的派生类型),然后尝试构建< em>派生类的临时实例,其中Component为输入。

换句话说,您的示例基本上是这样做的:

Component

错误意味着您的inline Color& getObject(const std::string& key) { TComponent *pcomp = _map.at(key); Color tmp(*pcomp); // <-- error here return tmp; } 类没有接受Color作为输入的构造函数,因此无法编译。

即使代码确实编译了,它仍然是错误的,因为你将一个引用返回给一个临时对象,当该函数退出时它会被破坏,所以调用者最终会有一个悬空引用无效的记忆。

正如@MikeVine在评论中所述,您可以编写这样的函数来修复它:

Component

这样可行,因为它消除了临时对象的构造,并返回对存储在地图中的现有对象的引用。

你也可以这样编写这样的函数:

template<typename U>
inline U& getObject(const std::string& key)
{
    return static_cast<U&>(*(_map.at(key)));
}

此代码首先将template <typename U> inline U& getObject(const std::string& key) { return *(static_cast<U*>(_map.at(key))); } 指针强制转换为Component*指针,然后取消引用它以访问派生类对象。

如果您在运行时不确定所请求的组件是否实际上是请求的类型,您可以添加一些额外的错误处理以确保在返回之前:

U*

可替换地:

template <typename U>
inline U& getObject(const std::string& key)
{
    U *ptr = dynamic_cast<U*>(_map.at(key));
    if (!ptr) throw std::invalid_argument("");
    return *ptr;
}