我在编译继承自此父类的子类时遇到以下错误:'ComponentManager' does not refer to a value
:
template<typename ComponentManager>
class component_collection {
protected:
int n_components;
int n_versions;
int first_blank;
int last_used;
std::vector<std::deque<shared_ptr<entity<ComponentManager>>>> entity_pointers;
public:
component_collection(int n_c, int n_v) :
n_components(n_c),
n_versions(n_v),
first_blank(0),
last_used(0),
entity_pointers(n_v, std::deque<shared_ptr<entity<ComponentManager>>>()) // <-- ERROR HERE
{}
...
};
我对如何在构造函数中使用std::vector
空n_v
初始化std::deque
感到困惑。
子类声明类似vector
deque
并按预期编译/工作(直到我将vector<deque>
添加到父级,即:)
template<typename ComponentManager>
class test_component_collection : public component_collection<ComponentManager> {
std::vector<std::deque<int>> values;
public:
test_component_collection(int n_c, int n_v) :
component_collection<ComponentManager>(n_c, n_v),
values(n_v, std::deque<int>()) // <-- NO ERROR HERE
{ }
...
};
所以这似乎与std::shared_ptr<entity<ComponentManager>>
的容器有关,但我不明白为什么会出现这个问题(entity
标头包含在内,需要<ComponentManager>
1}}正如您所期望的那样,并且在使用所有这些类时提供了ComponentManager
。
我显然错过了一些东西......
更新
以下是entity
的代码:
template<typename ComponentManager>
class entity {
protected:
ComponentManager & component_manager;
public:
entity(ComponentManager & cm) : component_manager(cm) {}
void initialise_components(shared_ptr<entity<ComponentManager>> sp) {}
};
在component_collection
的顶部添加它似乎解决了问题(至少编译错误,我没有彻底测试结果):
template<typename ComponentManager> using entity_ptr_deque = std::deque<shared_ptr<entity<ComponentManager>>>;
然后在适当时替换entity_ptr_deque<ComponentManager
。这有助于提高可读性,因此无论如何我都可以保留它,但它无助于理解错误,尤其是在最小的示例构建正常时(请参阅注释)。
更新2
使用评论中的Wandbox,我发现我的完整课程没有编译,而@VittorioRomeo编辑的版本确实如此。
在Wandbox上从Clang切换到GCC(我在本地使用Clang)给出了一个非常不同的错误消息:
declaration of 'auto component_collection<ComponentManager>::entity(int)'
changes meaning of 'entity'
这是在我添加std::vector<std::deque<shared_ptr<entity<ComponentManager>>>> entity_pointers;
和关联的构造函数更新之前存在的方法。它当然会在类定义中屏蔽名称entity
,因此会出错。 Clang的错误信息完全指向其他地方。
答案 0 :(得分:4)
Clang编译错误'X' does not refer to a value
可能会产生误导。
这意味着,在代码中的那一点,Clang期待值,而不是类型。但其原因可能与X
的性质无关。
可能是,无论X
传递给 ,都需要一个值而不是一个类型,即Clang不认为这是一个模板。
特别是在这种情况下:template<typename ComponentManager> entity
已被类中的方法屏蔽 - auto entity(int)
。这会更改entity
的含义,导致模板特化的站点出错,但不在正在进行屏蔽的方法的站点上。
GCC在这个实例中提供了更清晰的错误消息,所以值得尝试像Wandbox这样的工具来查看不同的编译器认为代码有什么问题。