g++模板参数错误
我有 GetContainer() 函数,如下所示。
template<typename I,typename T,typename Container>
Container& ObjCollection<I,T,Container>::GetContainer()
{
return mContainer;
}
当我按如下方式使用此方法时,
template<typename I,typename T>
T& DynamicObjCollection<I,T>::Insert(T& t)
{
GetContainer().insert(&t);
return t;
}
出现错误。
error: there are no arguments to ‘GetContainer’ that depend on a template parameter,
so a declaration of ‘GetContainer’ must be available
error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of
an undeclared name is deprecated)
它与 MSVC 一起工作得很好,但 g++ 就不那么宽容了。代码有什么问题吗?
I have GetContainer() function as follows.
template<typename I,typename T,typename Container>
Container& ObjCollection<I,T,Container>::GetContainer()
{
return mContainer;
}
When I use this method as follows
template<typename I,typename T>
T& DynamicObjCollection<I,T>::Insert(T& t)
{
GetContainer().insert(&t);
return t;
}
I got errors.
error: there are no arguments to ‘GetContainer’ that depend on a template parameter,
so a declaration of ‘GetContainer’ must be available
error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of
an undeclared name is deprecated)
It works fine with MSVC, but g++ is not so permissive. What's wrong with the code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我注意到
GetContainer
函数是ObjCollection
的一个方法,而Insert
是DynamicObjectCollection
的成员。由此,我假设DynamicObjectCollection
继承自ObjectCollection
。如果确实如此,问题就在于当您编写从模板基类继承的模板类时,名称查找的工作方式与普通类中的名称查找略有不同。特别是,您不能仅使用基类成员的名称来引用它们;您需要向编译器指示在哪里查找名称。这在 Visual Studio 中起作用的原因是 Microsoft C++ 编译器实际上错误地理解了这种行为,并允许技术上非法的代码正常编译。
如果您想调用基类的 GetContainer 函数,您有两种选择。首先,您可以显式指示调用是对成员函数:
现在编译器知道
GetContainer
是DynamicObjectCollection
的成员,它知道它可能需要查看在基类中调用GetContainer
,因此它将推迟名称查找,直到实例化模板。另一个可用的选项是在类主体中添加一个
using
声明:这也明确地向编译器表明
GetContainer
可以在基类中定义,因此它推迟查找直到模板实例化。如果这不适用于您的情况,请告诉我,我可以删除这篇文章。
希望这有帮助!
I noticed that the
GetContainer
function is a method ofObjCollection
, whileInsert
is a member ofDynamicObjectCollection
. From this, I'm going to assume thatDynamicObjectCollection
inherits fromObjectCollection
.If this is indeed the case, the problem is that when you write a template class that inherits from a template base class, the way that name lookup works is slightly different from name lookup in normal classes. In particular, you cannot just reference base class members using their names; you need to indicate to the compiler where to look for the name. The reason this works in Visual Studio is that the Microsoft C++ compiler actually gets this behavior wrong and allows code that is technically illegal to compile just fine.
If you want to invoke the
GetContainer
function of the base class, you have two options. First, you can explicitly indicate that the call is to a member function:Now that the compiler knows that
GetContainer
is a member ofDynamicObjectCollection
, it knows that it might need to look upGetContainer
in the base class, and so it will defer name lookup until the template is instantiated.The other option available would be to add a
using
declaration into the class body:This also indicates unambiguously to the compiler that
GetContainer
may be defined in the base class, and so it defers lookup until template instantiation.If this isn't applicable to your situation, let me know and I can delete this post.
Hope this helps!