C++ “无法从“A”转换为“B&”
我正在使用模板元编程构建实体组件系统。我经常遇到无法从[base type]转换为[type user requested]&或无法将NullComponent转换为[type user requested]&错误: 编辑 这些选项目前似乎有效C++ “无法从“A”转换为“B&”,c++,templates,c++11,null-object-pattern,C++,Templates,C++11,Null Object Pattern,我正在使用模板元编程构建实体组件系统。我经常遇到无法从[base type]转换为[type user requested]&或无法将NullComponent转换为[type user requested]&错误: 编辑 这些选项目前似乎有效 template<typename C> const C& Entity::GetComponent() const { for(auto& uc : _components) { auto* c =
template<typename C>
const C& Entity::GetComponent() const {
for(auto& uc : _components) {
auto* c = dynamic_cast<C*>(uc.get());
if(c && std::is_base_of<a2de::IComponent&, C&>().value && std::is_same<decltype(c), C&>().value) {
return *c;
}
}
throw std::runtime_error(std::string("Component not available."));
}
或
从较高的层次上看,从我的理解来看,返回类型不能用于定义模板类型。参数列表可以用于定义模板类型 例如,这可能会起作用-
template<typename C>
void Entity::GetComponent(C *obj) {
for(auto c : _components) {
if(std::is_base_of<a2de::IComponent&, C&>().value && std::is_same<decltype(c), C&>().value) {
obj = c; //<-- error here
return;
}
}
obj = NULL;
return; //<-- and here
}
希望这能有所帮助。至少有三件事: 在GetComponent中,您迭代unique_ptr元素,并将其类型always std::unique_ptr与std::is_same中的其他元素进行比较。您可能不希望这样。 在最终返回中,您似乎返回了对临时的引用。 return*c需要动态_转换,除非c==IComponent。 编辑 此外: std::is_base_of对引用毫无意义。即使使用类NullComponent:IComponent{};,您仍然会得到std::is_base_of::value==false。 并且您不检查nullptr 最后,在我看来,您应该将for循环替换为
for(auto& component : _components) {
auto* c = dynamic_cast<C*>(component.get());
if (c)
{
return *c;
}
}
如果你发布了一个你想要编译的完整示例,那么分析就会变得更容易。当前代码缺少includes、IComponent和NullComponent。你忘了在decltype中使用c吗?->std::is_same.value->std::is_same.value在似乎现在可以使用的解决方案中,为什么需要std::is_base_of和std::is_same?不是动态的_cast会处理您需要的所有内容吗?另外,我非常确定的是,的is_base_中的引用会阻止代码正常工作。
template<typename C>
void Entity::GetComponent(C *obj) {
for(auto c : _components) {
if(std::is_base_of<a2de::IComponent&, C&>().value && std::is_same<decltype(c), C&>().value) {
obj = c; //<-- error here
return;
}
}
obj = NULL;
return; //<-- and here
}
for(auto& component : _components) {
auto* c = dynamic_cast<C*>(component.get());
if (c)
{
return *c;
}
}