g++模板参数错误

发布于 2024-10-21 19:32:21 字数 755 浏览 1 评论 0原文

我有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉南桥 2024-10-28 19:32:21

我注意到GetContainer函数是ObjCollection的一个方法,而InsertDynamicObjectCollection的成员。由此,我假设 DynamicObjectCollection 继承自 ObjectCollection

如果确实如此,问题就在于当您编写从模板基类继承的模板类时,名称查找的工作方式与普通类中的名称查找略有不同。特别是,您不能仅使用基类成员的名称来引用它们;您需要向编译器指示在哪里查找名称。这在 Visual Studio 中起作用的原因是 Microsoft C++ 编译器实际上错误地理解了这种行为,并允许技术上非法的代码正常编译。

如果您想调用基类的 GetContainer 函数,您有两种选择。首先,您可以显式指示调用是对成员函数:

this->GetContainer().insert(&t);

现在编译器知道 GetContainerDynamicObjectCollection 的成员,它知道它可能需要查看在基类中调用 GetContainer,因此它将推迟名称查找,直到实例化模板。

另一个可用的选项是在类主体中添加一个 using 声明:

template <typename I, typename T>
class DynamicObjectCollection: public ObjectCollection<I, T, /* ? */> {
public:
    using ObjectCollection<I, T, /* ? */>::GetContainer;

    /* ... */
};

这也明确地向编译器表明 GetContainer 可以在基类中定义,因此它推迟查找直到模板实例化。

如果这不适用于您的情况,请告诉我,我可以删除这篇文章。

希望这有帮助!

I noticed that the GetContainer function is a method of ObjCollection, while Insert is a member of DynamicObjectCollection. From this, I'm going to assume that DynamicObjectCollection inherits from ObjectCollection.

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:

this->GetContainer().insert(&t);

Now that the compiler knows that GetContainer is a member of DynamicObjectCollection, it knows that it might need to look up GetContainer 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:

template <typename I, typename T>
class DynamicObjectCollection: public ObjectCollection<I, T, /* ? */> {
public:
    using ObjectCollection<I, T, /* ? */>::GetContainer;

    /* ... */
};

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文