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<TV>
问题是: 从标准的角度来看,第一个选项是否正确? 是否可以让第一个选项与 MinGW 一起使用?
【问题讨论】:
【参考方案1】:MinGW 是正确的。不可能仅仅因为QStringList
是模板的派生类而从QStringList
推导出TC
和TV
。在标准(C++11,§14.8.2.5/8)中有一个函数调用的推断上下文列表,TT<T>
是其中之一,其中TT
是模板模板参数,T
是模板类型参数。但是,从模板特化派生的类本身并不是模板特化。此外,虽然QStringList
类型的左值可以隐式转换为QList<QString>
,但模板参数推导不考虑大多数类型的隐式转换。
另外,是的,您确实需要typename
。有关原因的解释,请参阅Where and why do I have to put the "template" and "typename" keywords?
该标准还规定,允许实现接受根据该标准格式错误的代码作为扩展。 Visual C++ 有很多扩展,所以它接受很多不符合标准的代码。
【讨论】:
【参考方案2】:没有,也没有。该标准要求从属名称使用 typename 关键字。 MSVC 不允许这样做。当涉及到标准合规性时,永远不要相信 MSVC。他们只是永远不会完全正确。
【讨论】:
以上是关于MinGW 不识别从模板类继承为模板的主要内容,如果未能解决你的问题,请参考以下文章