【发布时间】:2014-10-26 17:32:46
【问题描述】:
我有一个非模板类,其模板成员函数类似于下面。
class Component
{
public:
static const int HASH_ID = 0;
virtual int HashID() const {return Component::HASH_ID;}
virtual bool is(int hash_id) const {return Component::HASH_ID == hash_id;}
template<typename T> bool is() const {return this->is(T::HASH_ID);}
};
class Transform : public Component
{
public:
static const int HASH_ID = 1;
virtual int HashID() const {return Transform::HASH_ID;}
virtual bool is(int hash_id) const {return Transform::HASH_ID == hash_id;}
};
我的问题是 Transform 类不允许我调用模板函数。
这是我写的无法编译的测试代码
int main(void)
{
Transform test_component;
Transform* transform = &test_component;
Component* component = &test_component;
std::cout << component->is<Transform>() << std::endl; //No issues
//Won't compile unless I comment out this line
std::cout << transform->is<Transform>() << std::endl; //Says I am missing argument list
std::cout << transform->is(Transform::HASH_ID) << std::endl; //Works Fine!
return 0;
}
任何想法为什么这不起作用?
【问题讨论】:
-
将此行添加到
Transform:using Component::is;。名称查找的工作方式是,Transform::is从基类中隐藏所有名为is的实体,无论是否具有匹配签名。然后using声明将名称从基类范围带入Transform的范围,因此它们不再被隐藏。从长远来看,最好给两个函数起不同的名称,否则你会一直遇到这个问题。 -
完美!我会做更多的测试,如果它需要一个新的名字,我会改变它。有道理。
-
@IgorTandetnik 如果他给它起不同的名字,那不会阻止派生类被多态使用吗?
-
我不相信他的意思是每个人都需要一个新名字。我认为他的意思是使用除“is”之外的其他名称。问题是重载函数“is”的虚拟版本会导致所有名为“is”的基类函数被隐藏。如果它在基类中有除“is”之外的任何其他名称,则它在派生时不会被隐藏。所以我可以简单地称它为“isTemplate”,它适用于所有派生类。
标签: c++ function templates member