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一起使用?
答案 0 :(得分:1)
不,不。标准需要依赖名称的typename关键字。 MSVC不允许这样做。在标准合规性方面,永远不要相信MSVC。他们从未完全正确。
答案 1 :(得分:1)
MinGW是正确的。不应仅仅因为TC
是模板的派生类而从TV
中推断QStringList
和QStringList
。标准中有函数调用的推导上下文列表(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 ++有很多扩展,因此它接受了许多不符合标准的代码。