c++constructorcastingoperator-overloadingtemplate-classes

C++ program compiles in Visual Studio 2010 but not Mingw


The program below compiles in VS 2010, but not in a recent version of Mingw. Mingw gives me the error "conversion from int to non-scalar type 'tempClass(it)' requested". Class "it" is just a simple class to use in the template for the purpose of illustration.

#include <iostream>
#include <string>

using namespace std;

template <class T>
class tempClass{
    public:
    T theVar;

    tempClass(){}

    tempClass(T a){
        theVar = a;
    }

/*  tempClass <T> & operator = (T a){
            (*this) = tempClass(a);
            return *this;
    }
*/
};

class it{
    public:

    int n;

    it(){}

    it(int a){
        n = a;
    }
};

int main(){
    tempClass <it> thisOne = 5;         // in MinGW gives error "conversion from int to non-scalar type 'tempClass(it)' requested"
    cout << thisOne.theVar.n << endl;   // in VS 2010 outputs 5 as expected
}

Commenting in/out the assignment operator portion doesn't seem to make a difference - I didn't expect it to, I just included it because I also hope to do things like tempClass <it> a = 5; a = 6;, in case this is relevant to the answer.

My question is, how can I get this syntax to work as desired?


Solution

  • MinGW is correct to refuse the code since it relies on two implicit user-defined conversions. One from int to it and one from it to tempClass<it>. Only one user-defined implicit conversion is allowed.

    The below works since it only requires one implicit conversion:

    tempClass<it> thisOne = it(5);
    

    You can also let the constructor do the conversion which will let you do
    tempClass<it> thisOne = 5;. In the below example the constructor will accept any argument and will try to initialize theVar with it. If U is convertible to T, it'll compile and work as expected. Otherwise you'll get a compilation error about an invalid conversion.

    template<class T>
    class tempClass {
    public:
        template<typename U>
        tempClass(U a) : theVar(a) {}
    
    //private:
        T theVar;
    };
    

    Demo