导出依赖类型的静态成员函数返回值的正确语法

correct syntax for deducing return value of static member function of dependent type

本文关键字:返回值 语法 函数 静态成员 依赖 类型      更新时间:2023-10-16

我不知道导出依赖类型静态成员函数返回值的正确语法。我已经尝试了十几种组合,包括使用::std::result_of,但它们似乎都不起作用。下面是看起来最有希望的变体(至少在非模板上下文中有效):

struct
t_In
{
};
struct
t_Out
{
    static auto
    Method(t_In &) -> t_Out
    {
        return(t_Out());
    }
};
template<typename tp_Out, typename tp_In, typename tp_Enable = void> struct
t_Template;
template<typename tp_Out, typename tp_In> struct
t_Template
<
    tp_Out
,   tp_In
,   typename ::std::enable_if
    <
        ::std::is_same
        <
            decltype
            (
                ::std::remove_cv // adding typename here makes Method look like type
                <
                    typename ::std::remove_reference
                    <
                        tp_Out
                    >::type
                >::type::Method(::std::declval<tp_In>()) // Err: does not evaluate to function ...
            )
        ,   tp_Out
        >::value
    >::type
>
{
};

编辑:编译VS2013,请注意,我甚至没有实例化任何东西,错误只是从这个模板单独弹出

您的问题之一是std::declval返回一个右值引用,它不能绑定到非const左值引用,如t_In&

一个相当干净的解决方案是使用void_tstd::declval<tp_In&>:

//standard void_t implementation
template <typename...> struct voider { using type = void; };
template <typename...Ts> using void_t = typename voider<Ts...>::type;
//primary template
template<typename tp_Out, typename tp_In, typename tp_Enable = void>
struct t_Template;
//for when tp_Out has a static member function called Method 
//taking an lvalue reference to tp_In
template<typename tp_Out, typename tp_In>
struct t_Template
<tp_Out, tp_In, void_t<decltype(tp_Out::Method(std::declval<tp_In&>()))>>
{
};

template<typename tp_Out, typename tp_In> struct
t_MethodReturnValueDeducer
{
    typedef decltype
    (
        ::std::remove_cv
        <
            typename ::std::remove_reference
            <
                tp_Out
            >::type
        >::type::Method(::std::declval<tp_In &>())
    ) t_Deduced; 
};
template<typename tp_Out, typename tp_In, typename tp_Enable = void> struct
t_Template;
template<typename tp_Out, typename tp_In> struct
t_Template
<
    tp_Out
,   tp_In
,   typename ::std::enable_if
    <
        ::std::is_same
        <
            typename t_MethodReturnValueDeducer<tp_Out, tp_In>::t_Deduced
        ,   tp_Out
        >::value
    >::type
>
{
};

我希望这将有助于人们仍然挣扎在VS2013…