MinGW无法识别从模板类继承的模板

时间:2014-05-07 21:09:09

标签: c++ qt templates c++11 mingw

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);
}

潜在的错误似乎是:

  
    

无法推断'TC&lt; TV&gt;'的模板来自非模板类型'QStringList'

  

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>

问题是:
从标准的角度来看,1-st选项是否正确? 是否有可能让1-st选项与MinGW一起使用?

2 个答案:

答案 0 :(得分:1)

不,不。标准需要依赖名称的typename关键字。 MSVC不允许这样做。在标准合规性方面,永远不要相信MSVC。他们从未完全正确。

答案 1 :(得分:1)

MinGW是正确的。不应仅仅因为TC是模板的派生类而从TV中推断QStringListQStringList。标准中有函数调用的推导上下文列表(C ++ 11,§14.8.2.5/ 8),TT<T>就是其中之一,其中TT是模板模板参数,{ {1}}是模板类型参数。但是,从模板特化派生的类本身不是模板特化。此外,虽然类型T的左值可隐式转换为QStringList,但模板参数推导不考虑大多数类型的隐式转换。

此外,是的,您确实需要QList<QString>。有关原因的说明,请参阅Where and why do I have to put the "template" and "typename" keywords?

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