编译器报告的模板替换期间出错
Error during template substitution reported by compiler
我看到一个正确的构建错误,但由于替换失败不是错误规则,我预计会忽略一些内容:
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);
编译器正在尝试实例化我添加了注释的函数,它没有这样做是正确的。我不明白的是,如果我删除它,那么编译器 将 select 正确的函数 (header 末尾的专业化)和继续快乐地前进。
在我看来,我看到的错误是在替换期间发生的,因此编译器应该默默地丢弃 std::vector<T>
候选并返回到专业化。为什么这没有发生?
发生这种情况是因为 SFINAE 仅适用于 "immediate context",即模板参数本身。
通过将有问题的实例化移动到模板参数中,可以将错误转化为替换失败,如下所示:
template<typename T, typename = T&&>
array<T>^ clr_cast(std::vector<T> value)
function
{
[memcpy]
}
代码现在编译成功,并选择了适当的 clr_cast
重载。
我看到一个正确的构建错误,但由于替换失败不是错误规则,我预计会忽略一些内容:
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);
编译器正在尝试实例化我添加了注释的函数,它没有这样做是正确的。我不明白的是,如果我删除它,那么编译器 将 select 正确的函数 (header 末尾的专业化)和继续快乐地前进。
在我看来,我看到的错误是在替换期间发生的,因此编译器应该默默地丢弃 std::vector<T>
候选并返回到专业化。为什么这没有发生?
发生这种情况是因为 SFINAE 仅适用于 "immediate context",即模板参数本身。
通过将有问题的实例化移动到模板参数中,可以将错误转化为替换失败,如下所示:
template<typename T, typename = T&&>
array<T>^ clr_cast(std::vector<T> value)
function
{
[memcpy]
}
代码现在编译成功,并选择了适当的 clr_cast
重载。