成员函数上的boost :: enable_if,重载返回类型

时间:2019-07-10 19:12:06

标签: c++ templates boost template-meta-programming c++03

我希望能够使用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
    }
};

2 个答案:

答案 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的检查,如果不是,则发出编译时错误。