下面是一个例子:
template <class T, typename std::enable_if<!std::is_fundamental<T>::value, int >::type = 0 >
class Calc
{
public:
int operator()( const T& v ) const {
return v.getValue();
}
};
template <class T, typename std::enable_if<std::is_fundamental<T>::value, int >::type = 0 >
class Calc : CalcBase <T>
{
};
在编译时,我得到以下错误:
c.cpp:26: error: template parameter 'typename std::enable_if<(! std::is_fundamental::value), int>::type <anonymous>'
c.cpp:36: error: redeclared here as 'typename std::enable_if<std::is_fundamental::value, int>::type <anonymous>'
这里的目的是选择Calc的版本,如果传递的模板参数是一个类,则该版本将覆盖基类函数调用运算符。如果传递的参数是基本类型,那么我们选择不覆盖基类功能的Calc版本。你能帮助我了解如何让它工作吗?
2条答案
按热度按时间kuarbcqp1#
我不认为类模板声明与SFINAE一起工作:类模板不像函数模板那样被重载。您声明了两个同名的主类模板,这是不允许的。
方便的是,SFINAE对于您的用例不是必需的:类模板支持部分专门化。您只需使用默认的
bool
参数,并根据trait是true
还是false
来专门化类模板。例如:kmb7vmvb2#
将SFINAE与类模板一起使用的一种方法是通过使用SFINAE专门化模板参数的部分专门化。
下面是一个实现问题中描述的类的最小工作示例。
在
Calc
的示例化中,模板参数U
要么具有默认类型void
,要么具有类型void
,但通过enable_if
条件为true
,或者如果enable_if
条件为false
,则涉及SFINAE类型错误。由于
U
具有void
的默认参数,因此导致所有部分专门化的SFINAE类型错误的类型T
仍然会导致基于默认参数的类模板的示例化,并避免编译时错误。注意:在这个特定的例子中,其中一个条件必须是true
,但是在其他情况下,使用默认参数会有所帮助。