我要达到的目标:
我有以下类Request,它具有自己的模板函数。我想用两种状态来称呼它:
1)具有提供的参数;
2)仅使用一个参数,其他参数应默认创建

template <typename TCmd> class Request{
    public:
    Request(TCmd applyingCommand): cmd(applyingCommand){}
    template<typename ...TReplyData> void onSuccess(TReplyData... args){
        //  cmd(true, args...);
    }
    void onFail(){
         // cmd(false) //here I want to create a wrapper, who calls the cmd with false + empty arguments
                       //which should be created by their constructor.
    }
    TCmd cmd;
};

这里是我要如何使用它:

auto lambda = [](bool isSucceed, int v, std::vector<uint> vec){
        //doing smth
        qDebug() << "insideLamda" << isSucceed << v << vec;
    };
    std::function<void(bool, int, std::vector<uint>)> fu = lambda;
    Request req(fu);
    req.onSuccess(4, std::vector<uint>{1,2});
    req.onFail();

所以这是我的想法,如何实现它,但我坚持使用元组和可变参数模板
关键是创建以下函数包装

template <typename ...Args> class CmdFu
{
public:
    explicit CmdFu(std::function<void(Args...)> f): m_function(f){
    }
    template <typename ...ProvidedArgs>void call(ProvidedArgs... args){
        m_function(args...);
    }
    template <typename ...ProvidedArgs>void callWithDefault(ProvidedArgs...args){ //here
        auto neededIndecies = std::make_index_sequence<sizeof... (Args)>{};
        size_t sizeOfRemainingIndecies = sizeof... (Args) - sizeof... (args);
        callDefault(neededIndecies, args...);
    }
private:
    template<class T> T create(){
        T t; return t;
    }
     template <typename ...ProvidedArgs, size_t...indecies> void callDefault( std::index_sequence<indecies...>, ProvidedArgs...args){
        auto providedTuple = std::make_tuple(args...);
        auto providedIndecies = std::index_sequence_for<ProvidedArgs...>();
        //Approach #1: I create whole default tuple and somehow applying my provided Tuple to it
        // NeededTuple t;
        // ResultTuple r??
        // std::apply(m_function, r);

        //Aprroach #2: I make std::index_sequence with remaining indexes, like 2,3,4,5 and create remaining tuple
        //then make the resulting tuple with std::tuple_cat
        // also std::apply
    }
    size_t sizeOfNeededIndecies;
    std::function<void(Args...)> m_function;
    using NeededTuple = std::tuple<Args...>;
};


这是我的主要问题:
1)如何将我自己的参数设置为默认元组?
2)如何创建具有开始sizeOfRemainingIndecies的index_sequence?
3)可以检查调用签名以避免在call()内运行时崩溃吗?

最佳答案

如果您不包装std::function,但保留函子,您可能已经这样做了

auto lambda = [](bool isSucceed, int v = 0, std::vector<uint> vec = {}){
    //doing smth
    qDebug() << "insideLamda" << isSucceed << v << vec;
};
Request req(lambda);
req.onSuccess(4, std::vector<uint>{1,2});
req.onFail();

Demo

对于CmdFu实现,您可以执行以下操作:
template <typename ...Args> class CmdFu
{
public:
    explicit CmdFu(std::function<void(Args...)> f): m_function(f){}

    template <typename ...Ts>
    void call(Ts&&... args){
        m_function(std::forward<Ts>(args)...);
    }

    template <typename ...Ts>
    void callWithDefault(Ts&&...args)
    {
        callDefaultImpl<sizeof...(Ts)>(std::make_index_sequence<sizeof...(Args)
                                                                - sizeof...(Ts)>{},
                                       std::forward<Ts>(args)...);
    }
private:

    template <std::size_t Offset, size_t...Is, typename ...Ts>
    void callDefaultImpl(std::index_sequence<Is...>, Ts&&...args){
        m_function(std::forward<Ts>(args)...,
                   std::tuple_element_t<Offset + Is, std::tuple<Args...>>{}...);
    }
    std::function<void(Args...)> m_function;
};

Demo



创建默认的缺少参数的操作如下:
std::tuple_element_t<Offset + Is, std::tuple<Args...>>{}...



您可以创建常规索引序列和偏移量:
template <std::size_t Offset, std::size_t... Is>
constexpr std::index_sequence<(Offset + Is)...>
index_sequence_with_offset(std::index_sequence<Is...>)
{ return {}; }



如果签名不匹配,它将无法编译,如果需要,可以使用SFINAE丢弃无效的重载。可能有几种语法,例如:
template <typename ...Ts>
auto call(Ts&&... args)
-> decltype(m_function(std::forward<Ts>(args)...), void())
{
    m_function(std::forward<Ts>(args)...);
}

关于c++ - 使用一半参数运行任何仿函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57991245/

10-11 23:17
查看更多