2012-12-18 41 views
2

为什么在VS 2010中请帮助我了解为什么SFINAE没有在这种情况下工作

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>(); 
    } 

结论:模板甚至成员必须强制模板成员函数做SFINAE在2010年MSVC

+0

错误是出现什么线?另外,你是否仅仅基于返回类型重载'Clear()'?这是不可能的。 – iammilind

+0

这不是真正的超载,因为只有一个是有效的。另一个有替代失败。编译器只能考虑一个。很显然,我的理解有些错误。 – doug65536

+0

第一个清除定义有错误。我认为SFINAE会永远失败,没有:: type(如果你知道我的意思)。 – doug65536

回答

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() 
{ 
    ... 
} 

编辑:新增Titem作为默认参数,按照马蒂厄M.的建议。

+1

你是在正确的轨道上,但有更简单:使用能力为默认模板参数=>'模板'。这样,Clear方法就是模板*,但用户不需要担心。 –

+0

@MatthieuM。好主意。我将编辑它。 –

+0

嘿,成员函数上的默认模板参数是不是非法的?只有类(和结构)可以有默认的模板参数,对吗? – doug65536

相关问题