【问题标题】:boost::enable_if on member function, overload return typeboost::enable_if 在成员函数上,重载返回类型
【发布时间】:2023-04-09 06:41:01
【问题描述】:

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

对于整数类型,我想从 operator() 返回 TypeToReturn 对于其他类型我想返回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++ templates boost template-meta-programming c++03


    【解决方案1】:

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

    【讨论】:

    • 这可能不适用于具有此默认模板参数的 c++03?
    • @Newbie:确实,增加了版本限制。
    【解决方案2】:

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

    【讨论】:

    • 哦,谢谢,但不能解决“const typename .... disable_if.....不能重载”的问题
    • 你是否也提供了 TypeToReturn ?
    • godbolt.org/z/0lLydC 您可以使用稍微不同的方法来使用 enable/disable_if
    • @alexrider 这不适用于 int 数组? godbolt.org/z/PaHGYQ(也许不是最好的)在这种情况下它不是“整体”,所以我想返回 const &
    • 我的意思是当 TypeToReturn 将是数组,所以 operator() 应该返回 const TypeToReturn&
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 2011-06-20
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多