编译器

时间:2017-08-09 18:43:31

标签: c++11 templates visual-c++ c++-cli sfinae

我看到一个正确的构建错误,但由于替换失败不是错误规则,我希望忽略这个错误:

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 个答案:

答案 0 :(得分:0)

这是因为SFINAE仅适用于“直接上下文”,即模板参数本身。

通过将有问题的实例化移动到模板参数中,可以将错误转换为替换失败,如下所示:

typeof(IEnumerable<>)

现在代码编译成功,并选择了适当的ToList重载。