请帮助我理解为什么SFINAE在这种情况下不起作用

时间:2012-12-18 07:50:30

标签: c++ sfinae typetraits

为什么这在VS 2010中不起作用

  typename std::enable_if<!std::has_trivial_destructor<Titem>::value, BOOL>::type
  Clear()
    {
        ...
    }

  typename std::enable_if<std::has_trivial_destructor<Titem>::value, BOOL>::type
  Clear()
    {
        ...
    }

它位于模板类中。

我收到以下错误:

error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test,_Type>'

关于SFINAE错误。显然替换失败是一个错误。我知道它可能只是优化了析构函数调用,所以这不是一个真正的现实场景。每次我认为我终于理解了SFINAE,当我尝试使用它时它仍然不起作用。

在回应一些评论时(仅通过返回值关注过载),我已将其更改为虚拟参数技术。

这有效:

  template<typename U>
  BOOL _Clear(typename std::enable_if<!std::has_trivial_destructor<U>::value>::type *dummy = 0)
  {
     ...
  }

  template<typename U>
  BOOL _Clear(typename std::enable_if<std::has_trivial_destructor<U>::value>::type *dummy = 0)
  {
     ...
  }

  BOOL Clear()
  {
    return _Clear<Titem>();
  }

结论:即使是模板成员也必须强制模板化成员函数才能在MSVC 2010中执行SFINAE。

1 个答案:

答案 0 :(得分:3)

作为一个自己并不完全确定SFINAE的许多细节的人,我会冒昧地说问题是你的函数没有模板化 - 因此编译器不允许丢弃它们,即使它们被证明是非法的

尝试

template<typename T = Titem>
typename std::enable_if<std::has_trivial_destructor<T>::value, BOOL>::type
Clear()
{
    ...
}

template<typename T = Titem>
typename std::enable_if<!std::has_trivial_destructor<T>::value, BOOL>::type
Clear()
{
    ...
}

编辑:根据Matthieu M.的建议,添加Titem作为默认参数。