Question

MinGW (gcc version 4.8) fails to compile the following code:

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

the underlying error appears to be:

can't deduce a template for 'TC<TV>' from non-template type 'QStringList'

But QStringList is a standard Qt type and is declared as following:

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

so, I expect it is template too.

A few notes:
MSVC++2010 is able to compile this code with no errors.

Also I can get working code in MinGW by the following change:

template<class TC> void foo(TC & container)
{
    // container items type is resolved via TC::value_type here
    std::cout << sizeof(typename TC::value_type);
}

But in my opinion that makes the declaration of foo() less readable and it changes the meaning a bit, so I'd prefere to stay with the 1-st one option, i.e. TC<TV>

The questions are:
Is the 1-st option correct from standard point of view?
Is it possible to get the 1-st option working with MinGW?

Was it helpful?

Solution

MinGW is correct. It should not be possible to deduce TC and TV from QStringList simply because QStringList is a derived class of a template. There is a list of deduced contexts for function calls in the standard (C++11, §14.8.2.5/8) and TT<T> is one of them, where TT is a template template argument and T is a template type argument. However, a class that derives from a template specialization is not itself a template specialization. Furthermore, while an lvalue of type QStringList is implicitly convertible to QList<QString>, template parameter deduction does not consider most types of implicit conversions.

Also, yes, you do need typename. For an explanation of why, see Where and why do I have to put the "template" and "typename" keywords?

The Standard also says that an implementation is allowed to accept code that is ill-formed according to the Standard, as an extension. Visual C++ has a lot of extensions, so it accepts a lot of code that is not standard-compliant.

OTHER TIPS

No, and no. The Standard requires the typename keyword for dependent names. MSVC is bad for allowing that. Never trust MSVC when it comes to Standard compliance. They're just never quite completely right.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top