我希望能够使用boost::enable_if
来关闭/打开某些方法。
对于整数类型,我想从TypeToReturn
返回operator()
对于其他类型,我想返回const TypeToReturn&
这是我的尝试:
template<typename T>
struct Holder{
typedef T type;
};
template<typename First,
typename TypeToReturn = typename Holder<First>::type>
struct SuperClass{
typename boost::enable_if<boost::is_integral<TypeToReturn> >::type
operator()(int& someParameterNotImportant) const
{
// stuff
}
const typename boost::disable_if<boost::is_integral<TypeToReturn> >::type&
operator()(int& someParameterNotImportant) const
{
// stuff
}
};
我收到无法重载这些功能的错误消息。
我什至不确定这种尝试是否朝着正确的方向迈进。
编辑:在第一个建议之后,我将在更正后添加代码, 仍然出现“ const typename boost :: disable_if .....无法重载”的问题
template<typename T>
struct Holder{
typedef T type;
};
template<typename First,
typename TypeToReturn = typename Holder<First>::type>
struct SuperClass{
typename boost::enable_if<boost::is_integral<TypeToReturn>, TypeToReturn >::type
operator()(int& someParameterNotImportant) const
{
// stuff
}
const typename boost::disable_if<boost::is_integral<TypeToReturn>, TypeToReturn >::type&
operator()(int& someParameterNotImportant) const
{
// stuff
}
};
答案 0 :(得分:2)
SFINAE适用于模板方法。你不是。
在C ++ 11中,我们可以使用默认模板来处理该函数:
template<typename First,
typename TypeToReturn = typename Holder<First>::type>
struct SuperClass
{
template <typename T = TypeToReturn>
typename boost::enable_if<boost::is_integral<T>, T>::type
operator()(int& someParameterNotImportant) const
{
// stuff
}
template <typename T = TypeToReturn>
const typename boost::disable_if<boost::is_integral<T>, T>::type&
operator()(int& someParameterNotImportant) const
{
// stuff
}
};
C ++ 17将允许使用if constexpr
简化语法,
并且C ++ 20允许requires
由于特性而放弃该方法。
在C ++ 03中,我建议改为使用标签分配:
template<typename First,
typename TypeToReturn>
TypeToReturn helper(int& someParameterNotImportant, boost::true_type)
{
// stuff
}
template<typename First,
typename TypeToReturn>
const TypeToReturn& helper(int& someParameterNotImportant, boost::false_type)
{
// stuff
}
template<typename First,
typename TypeToReturn = typename Holder<First>::type>
struct SuperClass
{
typename boost::conditional<boost::is_integral<TypeToReturn>::value,
TypeToReturn,
const TypeToReturn&>::type
operator()(int& someParameterNotImportant) const
{
return helper<First, TypeToReturn>(someParameterNotImportant,
boost::is_integral<TypeToReturn>());
}
};
答案 1 :(得分:1)
您需要为enable_if提供类型
typename boost::enable_if<boost::is_integral<TypeToReturn>, TypeToReturn >::type
否则默认为空
要使其真正发挥作用,您需要自己制作操作员的模板函数,以允许SFINAE插入,这对于标签中所述的c ++ 03无效。
template <typename Ret = TypeToReturn>
typename boost::enable_if<boost::is_integral<Ret>,Ret >::type
operator()(int& someParameterNotImportant) const
或者使用伪变量并使运算符根据参数而不是返回值而有所不同。但是仍然保留它的模板。这将适用于c ++ 03
template<typename T>
TypeToReturn operator()(T& someParameterNotImportant, typename boost::enable_if<boost::is_integral<TypeToReturn>,T >::type* = 0) const
您还可以在此处添加T是否为int的检查,如果不是,则发出编译时错误。