mercredi 9 août 2017

Error during template substitution reported by compiler

I'm seeing a build error which is correct, but something that I would expect to be ignored due to the Substitution Failure Is Not An Error rule:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(895): error C3699: '&&': cannot use this indirection on type 'System::String ^'
RemoteWrapper.cpp(41): note: see reference to class template instantiation 'std::vector<System::String ^,std::allocator<_Ty>>' being compiled
        with
        [
            _Ty=System::String ^
        ]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(918): error C3699: '&&': cannot use this indirection on type 'System::String ^'

Here's the code which the error mentions:

std::string name;
clr_cast<String^>(name);

Here are the clr_cast templates:

template<typename TReturn, typename TSource>
TReturn clr_cast(TSource value)
{
    return (TReturn)value;
}

template<typename TReturn, typename TSource, typename = std::enable_if<!std::is_same<TReturn, TSource>>::value>
std::vector<TReturn> clr_cast(array<TSource>^ value)
{
    [iterate and cast]
}

template<typename T>
std::vector<T> clr_cast(array<T>^ value)
{
    [memcpy]
}

template<typename TReturn, typename TSource, typename = std::enable_if<!std::is_same<TReturn, TSource>>::value>
array<TReturn>^ clr_cast(std::vector<TSource> value)
{
    [iterate and cast]
}

template<typename T>
array<T>^ clr_cast(std::vector<T> value) // this is the problematic function
{
    [memcpy]
}

template<> std::string clr_cast(System::String^ value);
template<> System::String^ clr_cast(std::string value);

The compiler is trying to instantiate the function to which I added a comment and it's correct that it fails to do so. What I don't understand is that if I remove it then the compiler will select the correct function (the specialisation right at the end of the header) and continue happily onward.

It seems to me that the error I'm seeing is occurring during substitution, and that the compiler should therefore silently discard the std::vector<T> candidate and fall back on the specialisation. Why is this not happening?

Aucun commentaire:

Enregistrer un commentaire