【问题标题】:g++ template parameter errorg++模板参数错误
【发布时间】:2011-07-14 07:15:10
【问题描述】:

我有如下 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++ 不是那么宽松。代码有什么问题?

【问题讨论】:

  • 您能否发布一个完整的、可编译的示例来演示该问题?

标签: c++ templates g++


【解决方案1】:

我注意到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 可以在基类中定义,因此它将查找推迟到模板实例化。

如果这不适用于您的情况,请告诉我,我可以删除此帖子。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-15
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多