Ошибка при замене шаблона, сообщенная компилятором
Я вижу ошибку сборки, которая является правильной, но что-то, что я ожидал бы игнорировать из-за правила "Ошибка замены не является ошибкой":
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 ^'
Вот код, который упоминает ошибка:
std::string nativeString;
String^ clrString = clr_cast<String^>(nativeString);
Вот clr_cast
шаблоны:
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);
Компилятор пытается создать экземпляр функции, к которой я добавил комментарий, и это правильно, что он этого не делает. Чего я не понимаю, так это того, что если я удалю его, то компилятор выберет правильную функцию (специализация в конце заголовка) и продолжит счастливо.
Мне кажется, что ошибка, которую я вижу, происходит во время замены, и поэтому компилятор должен молча отбросить std::vector<T>
кандидат и отступить от специализации. Почему этого не происходит?
1 ответ
Это происходило потому, что SFINAE применяется только к "непосредственному контексту", то есть к самому параметру шаблона.
Ошибка может быть превращена в ошибку замещения путем перемещения проблемной реализации в параметры шаблона, например:
template<typename T, typename = T&&>
array<T>^ clr_cast(std::vector<T> value)
function
{
[memcpy]
}
Теперь код успешно компилируется, а соответствующий clr_cast
перегрузка выбрана.