首页 > 解决方案 > boost::enable_if 在成员函数上,重载返回类型

问题描述

我希望能够用来boost::enable_if关闭/打开某些方法。

对于我想要返回的整数类型对于我想要返回TypeToReturnoperator() 其他类型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
    }
};

标签: c++templatesboosttemplate-meta-programmingc++03

解决方案


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

推荐阅读