我对这个模板化方法有这个编译错误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并将其转换为特定类型以使用它时,我得到了上面的编译错误。我不明白为什么。
答案 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;
}