运行 任何具有一半参数的函子
Running any functor with half of arguments
我想达到什么目的:
我有以下 class 请求,它有自己的模板化功能。我想用两种状态来称呼它:
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();
对于 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;
};
1) How to set my own arguments to default tuple?
创建默认缺少的参数是通过以下方式完成的:
std::tuple_element_t<Offset + Is, std::tuple<Args...>>{}...
2) How to create index_sequence with starting sizeOfRemainingIndecies ?
您可以创建常规索引序列和偏移量:
template <std::size_t Offset, std::size_t... Is>
constexpr std::index_sequence<(Offset + Is)...>
index_sequence_with_offset(std::index_sequence<Is...>)
{ return {}; }
3) Is it possible to check the calling signature to avoid runtime crashes inside call()?
如果签名不匹配,它将无法编译,如果需要,您可以使用 SFINAE 丢弃无效的重载。有几种可能的语法,例如:
template <typename ...Ts>
auto call(Ts&&... args)
-> decltype(m_function(std::forward<Ts>(args)...), void())
{
m_function(std::forward<Ts>(args)...);
}
我想达到什么目的:
我有以下 class 请求,它有自己的模板化功能。我想用两种状态来称呼它:
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();
对于 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;
};
1) How to set my own arguments to default tuple?
创建默认缺少的参数是通过以下方式完成的:
std::tuple_element_t<Offset + Is, std::tuple<Args...>>{}...
2) How to create index_sequence with starting sizeOfRemainingIndecies ?
您可以创建常规索引序列和偏移量:
template <std::size_t Offset, std::size_t... Is>
constexpr std::index_sequence<(Offset + Is)...>
index_sequence_with_offset(std::index_sequence<Is...>)
{ return {}; }
3) Is it possible to check the calling signature to avoid runtime crashes inside call()?
如果签名不匹配,它将无法编译,如果需要,您可以使用 SFINAE 丢弃无效的重载。有几种可能的语法,例如:
template <typename ...Ts>
auto call(Ts&&... args)
-> decltype(m_function(std::forward<Ts>(args)...), void())
{
m_function(std::forward<Ts>(args)...);
}