MinGW 不识别从模板类继承为模板

Posted

技术标签:

【中文标题】MinGW 不识别从模板类继承为模板【英文标题】:MinGW does not recognize inherited from template class as a template 【发布时间】:2014-05-07 21:09:09 【问题描述】:

MinGW(gcc 4.8版)编译以下代码失败:

template<template<typename> class TC, typename TV> void foo(TC<TV> & container)

    // I need to deal with container items type here
    std::cout << sizeof(TV);


int main()

    QStringList list;
    foo(list);

潜在的错误似乎是:

无法从非模板类型“QStringList”推导出“TC”的模板

但是QStringList是一个标准的Qt类型,声明如下:

class QStringList : public QList<QString>  ... ;

所以,我希望它也是模板。

几点说明: MSVC++2010 能够无错误地编译此代码。

我还可以通过以下更改在 MinGW 中获得工作代码:

template<class TC> void foo(TC & container)

    // container items type is resolved via TC::value_type here
    std::cout << sizeof(typename TC::value_type);

但在我看来,这使得 foo() 的声明可读性降低,并且它的含义有所改变,所以我更愿意使用第一个选项,即 TC&lt;TV&gt;

问题是: 从标准的角度来看,第一个选项是否正确? 是否可以让第一个选项与 MinGW 一起使用?

【问题讨论】:

【参考方案1】:

MinGW 是正确的。不可能仅仅因为QStringList 是模板的派生类而从QStringList 推导出TCTV。在标准(C++11,§14.8.2.5/8)中有一个函数调用的推断上下文列表,TT&lt;T&gt; 是其中之一,其中TT 是模板模板参数,T 是模板类型参数。但是,从模板特化派生的类本身并不是模板特化。此外,虽然QStringList 类型的左值可以隐式转换为QList&lt;QString&gt;,但模板参数推导不考虑大多数类型的隐式转换。

另外,是的,您确实需要typename。有关原因的解释,请参阅Where and why do I have to put the "template" and "typename" keywords?

该标准还规定,允许实现接受根据该标准格式错误的代码作为扩展。 Visual C++ 有很多扩展,所以它接受很多不符合标准的代码。

【讨论】:

【参考方案2】:

没有,也没有。该标准要求从属名称使用 typename 关键字。 MSVC 不允许这样做。当涉及到标准合规性时,永远不要相信 MSVC。他们只是永远不会完全正确。

【讨论】:

以上是关于MinGW 不识别从模板类继承为模板的主要内容,如果未能解决你的问题,请参考以下文章

C++/CLI:从模板类继承的函数在 C# 中不可见

C++:从模板参数继承类

从祖先继承的 Django CMS 模板不识别占位符

用于接口或继承类的 ASP.NET MVC3 编辑器模板

c++ 泛型 模板继承问题

如何使用从解决方案中现有基类继承的 T4 模板生成类?