首页 > 解决方案 > 将嵌套类型层次结构展平为 std::function 的线性类型序列

问题描述

考虑这个(不工作的)代码。

template<class A, class B>
struct Param {
  typedef A A_t;
  typedef B B_t;
};


template<class P>
struct FuncType
{
  typedef std::function<void(typename P::A_t, typename P::B_t)> Func_t;
};


void foo(float a, float b,float c)
{
}


int main()
{
  // this doesn't work, as 2nd parameter is nested
  typedef Param< float , Param<float,float> > FloatFloatFloat;

  FuncType<FloatFloatFloat>::Func_t f = foo;

  f( .1 , .2 , .3 );
  
}

它适用于更简单的非嵌套参数构造:

void foo(float a, float b)
{
}


int main()
{    
  typedef Param< float , float > FloatFloat;

  FuncType<FloatFloat>::Func_t f = foo;

这个想法是让FuncType类模板Param在模板参数可以是简单的内置 C++ 类型或Param自身的类型上工作。换句话说:std::function参数列表应该包含嵌套类型中包含的所有内置Param类型。

这对 C++ 可行吗(可以是 C++20 之前的任何标准)?

标签: c++templates

解决方案


沿着这些思路,也许:

template<class A, class B>
struct Param {
  typedef A A_t;
  typedef B B_t;
};

template <typename T>
struct FlattenParam {
    using type = std::tuple<T>;
};

template <typename A, typename B>
struct FlattenParam<Param<A, B>> {
    using type = decltype(std::tuple_cat(
        std::declval<typename FlattenParam<A>::type>(),
        std::declval<typename FlattenParam<B>::type>()));
};

template<class P>
struct FuncType
{
  template <typename ...Ts>
  static std::function<void(Ts...)> helper(std::tuple<Ts...>);
  using Func_t = decltype(helper(std::declval<typename FlattenParam<P>::type>()));
};

演示


推荐阅读