通过参数计数推导重载成员函数的函数参数类型

deduce function parameter types of overloaded member function by argument count

目前我正在寻找一些方法来通过参数计数和实例类型获取重载成员函数的参数类型。 在我的例子中,我们知道名称、return 类型(void)和参数计数。 此外,不能有具有相同参数计数的第二个重载,并且函数永远不会被 cv 或 ref 限定。

样本:


#include <tuple>
#include <type_traits>
#include <iostream>

class TupleLikeType{
public:
    void Deconstruct(int& a, char& b){
      a = 12;
      b = 'A';
    }
    void Deconstruct(int& a, char& b, bool& c){
      Deconstruct(a, b);
      c = true;
    }
};

template<typename Type, std::size_t ArgCount>
class TupleDeconstructTypes{
public:
    using type = 
    //to implement
    std::conditional_t<ArgCount == 2, 
        std::tuple<int&, char&>, std::tuple<int&, char&, bool&>
    >
    //to implement end
    ;
};

template<typename T>
    class DeconstructAdapter
    {
    private:
        T& obj;
    public:
        template<
            typename DepT = T
            , typename... Args
        >
        constexpr void operator()(Args&&... args)
        {
            return obj.Deconstruct(std::forward<Args>(args)...);
        }
    public:
        constexpr DeconstructAdapter(T& toDeconstruct) : obj(toDeconstruct)
        {
        }
    };

template<typename Tuple>
class TupleWithOutRefs{};
template<template <typename...> typename Tuple, typename... T>
class TupleWithOutRefs<Tuple<T...>>{
public:
    using type = Tuple<std::remove_reference_t<T>...>;
};

template<
  std::size_t ArgCount
  ,typename T
  ,typename Args = typename TupleDeconstructTypes<T, ArgCount>::type
  ,typename TempTuple = typename TupleWithOutRefs<Args>::type

> 
auto CreateTuple(T& t){

    auto adapter = DeconstructAdapter(t);
    TempTuple result{};

    //std::apply calls std::invoke
    //during this call all out-references are bound to our allocated stack memory
    std::apply(adapter, result);

    return result;
}


int main(){
    //usage
    static_assert(std::is_same_v<
        TupleDeconstructTypes<TupleLikeType, 2>::type,
        std::tuple<int&, char&>
    >);

    TupleLikeType t;
    auto tuple = CreateTuple<2>(t);
    std::cout << std::get<0>(tuple);
}

你有什么想法以通用方式解决这个问题吗?

数量有限,你可以做这样的事情:

template <std::size_t Size>
struct helper;

template <>
struct helper<0>
{
    template <typename C>
    std::tuple<> operator() (void (C::*) ()) const;
};

template <>
struct helper<1>
{
    template <typename C, typename T1>
    std::tuple<T1> operator() (void (C::*) (T1)) const;
};

template <>
struct helper<2>
{
    template <typename C, typename T1, typename T2>
    std::tuple<T1, T2> operator() (void (C::*) (T1, T2)) const;
};

template <>
struct helper<3>
{
    template <typename C, typename T1, typename T2, typename T3>
    std::tuple<T1, T2, T3> operator() (void (C::*) (T1, T2, T3)) const;
};

// ...

template<typename Type, std::size_t ArgCount>
using TupleDeconstructTypes = decltype(helper<ArgCount>{}(&Type::Deconstruct));

Demo