mardi 27 mars 2018

MSVC: "error C2244: "unable to match function definition to an existing declaration"

The following code can be compiled with gcc(4.8 and up), while the MSVC (Visual Studio 2017, _MSC_VER 1910) gives error C2244: 'A::func': unable to match function definition to an existing declaration.

#include <iostream>

template<typename T, bool isInt= std::is_integral<T>::value >
class B
{
public:
    using RET = T;
};

template <typename T>
class B <T, false>
{
public:
    using RET = void;
};

template<typename T>
class A
{
    using type = T;
public:
    typename B<type>::RET func();
};

template<typename T>
typename B<typename A<T>::type>::RET A<T>::func()
{
    std::cout << "func" << std::endl;
    return 0;
}

int main()
{
    A<int> a;
    a.func();
    return 0;
}

Full error message from MSVC:

error C2244: 'A<T>::func': unable to match function definition to an existing declaration
note: see declaration of 'A<T>::func'
note: definition
note: 'B<A<T>::type,std::is_integral<T>::value>::RET A<T>::func(void)'
        with
        [
            T=A<T>::type
        ]
note: existing declarations
note: 'B<T,std::is_integral<_Ty>::value>::RET A<T>::func(void)'

It can compile if I eliminate the template specialization in class B.

template<typename T>
class B
{
public:
    using RET = T;
};

It can also compile if I don't use the type alias in class A.

template<typename T>
class A
{
public:
    typename B<T>::RET func();
};

template<typename T>
typename B<T>::RET A<T>::func()
{
    std::cout << "func" << std::endl;
    return 0;
}

And it can also compile if class A is not template.

class A
{
    using type = int;
public:
    typename B<type>::RET func();
};

It seems that the MSVC does not well support the mix use of template class, type alias and template specialization. I am not sure if there's a special term for this usage. Will the MSVC support this in newer version? Or any existing compile option can fix it?

Aucun commentaire:

Enregistrer un commentaire