【问题标题】:Create a function signature from a hana tuple without the preprocessor在没有预处理器的情况下从 hana 元组创建函数签名
【发布时间】:2018-02-27 13:31:11
【问题描述】:

有没有办法在没有预处理器的情况下做到这一点?

#include <boost/hana.hpp>
#include <boost/preprocessor.hpp>

namespace ba = boost::hana;

template <typename Arguments, unsigned ArgCount>
struct FunctionSigCreatorImpl {};

template <typename Arguments>
struct FunctionSigCreator : FunctionSigCreatorImpl<Arguments, decltype(ba::length(Arguments{}))::value>
{
};

#define DEF_ARG(z, n, data) \
    typename decltype(+ba::at(Arguments{}, ba::int_c<n>))::type

#define DEF_FUN_CREATOR(z, argCount, data)                                                  \
    template <typename Arguments>                                                         \
    struct FunctionSigCreatorImpl<Arguments, argCount>                                    \
    {                                                                                       \
        using Type = void(BOOST_PP_ENUM(argCount, DEF_ARG,));      \
    };

BOOST_PP_REPEAT(19, DEF_FUN_CREATOR,)

int main(int argc, char **argv)
{
    using MyTuple = ba::tuple<ba::type<int>, ba::type<long>, ba::type<char>>;
    static_assert(std::is_same<typename FunctionSigCreator<MyTuple>::Type, void(int, long, char)>::value);

    return 0;
}

【问题讨论】:

    标签: c++ boost boost-hana


    【解决方案1】:

    Boost.CallableTraits 可以通过 apply_return 做到这一点。

    #include <boost/callable_traits.hpp>
    #include <boost/hana.hpp>
    #include <tuple>
    #include <type_traits>
    
    namespace hana = boost::hana;
    namespace ct   = boost::callable_traits;
    
    template <typename Tuple>
    using to_function_sig = ct::apply_return_t<
      typename decltype(hana::unpack(Tuple{}, hana::template_<std::tuple>))::type,
      void
    >;
    
    int main()
    {
      using MyTuple = hana::tuple<hana::type<int>, hana::type<long>, hana::type<char>>;
      static_assert(std::is_same<to_function_sig<MyTuple>, void(int, long, char)>::value, "");
    }
    

    【讨论】:

    【解决方案2】:
    #include <boost/hana.hpp>
    #include <boost/hana/tuple.hpp>
    
    namespace ba = boost::hana;
    
    template<typename ... Types>
    ba::type<void(typename Types::type...)> FunctionSigCreatorImpl(ba::tuple<Types...>){ return{}; }
    
    template<typename Tuple>
    using FunctionSigCreator = decltype(FunctionSigCreatorImpl(std::declval<Tuple>()));
    
    int main()
    {
        using MyTuple = ba::tuple<ba::type<int>, ba::type<long>, ba::type<char>>;
        //using MyTuple = decltype(ba::tuple_t<int,long,char>);
        static_assert(std::is_same<typename FunctionSigCreator<MyTuple>::type, void(int, long, char)>::value);
    
        return 0;
    }
    

    【讨论】:

    • 这行得通,但 Hana 已经为此提供了设施。就像下面的 Jason 所示,您可以使用 hana::template_(还有其他类似 hana::metafunction)来更轻松地与类型级函数进行交互。如果这是你经常做的事情,我认为你会从使用这些而不是自己动手中受益。
    猜你喜欢
    • 2022-06-10
    • 1970-01-01
    • 2021-03-18
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 1970-01-01
    相关资源
    最近更新 更多