模板函数以及元组类型的子集的相应参数 [英] template function with corresponding parameters to subset of tuple types

查看:108
本文介绍了模板函数以及元组类型的子集的相应参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像这样写



multi_set< int,string,double,myType> m; //元组向量
m.insert(/ * some data * /);
m.find< 1,2>(something,2.123);

  m.find< 0,3>(1,instanceOfMyType); 
m.find< 1>(somethingelse);

其中 find 可以参数化,





我的代码到目前为止:

  < typename ... T> 
class multi_set {
typedef tuple< T ...>元组;
vector< tuple< T ...>> data = vector< tuple< T ...>>();

public:
void insert(T ... t){
data.push_back(tuple< T ...>(t ...));
}


模板< size_t ... Pos>
void find(???){
//然后我想使用这些参数搜索数据和
//返回第一个匹配项
}
}


解决方案

  /测试一个特定的元组是否是一个匹配
template< size_t ... Pos>
static bool is_match(const Tuple& tuple,const typename std :: tuple_element< Pos,Tuple> :: type& ... args){
std :: initializer_list< bool& results = {(std :: get< Pos>(tuple)== args)...};
return std :: all_of(results.begin(),results.end(),[](bool p){return p;});
}

//找到第一个匹配的。
template< size_t ... Pos>
typename vector< Tuple> :: const_iterator find(const typename std :: tuple_element< Pos,Tuple> :: type& ... args)const {
return std :: find_if(data.begin (),data.end(),[&](const Tuple& tup){return is_match< Pos ...>(tup,args ...);});
}

也可以有 find 采用类型参数包并且完全转发,而不是使用 tuple_element 获取固定类型。好处是,如果 == 是透明的,您可以避免不必要的转换。成本是,你不能采取任何不能完全转发任何东西(例如,支撑的初始化列表, 0 作为一个空指针常量)。另一个好处似乎是MSVC 2013在这个版本没有窒息:

  //测试一个特定的元组是否match 
template< size_t ... Pos,class ... Args>
static bool is_match(const Tuple& tuple,Args& ... args){
std :: initializer_list< bool> results = {(std :: get< Pos>(tuple)== std :: forward< Args>(args))...}
return std :: all_of(results.begin(),results.end(),[](bool p){return p;});
}

//找到第一个匹配的。
template< size_t ... Pos,class ... Args>
typename vector< Tuple> :: const_iterator find(Args& ... args)const {
return std :: find_if(data.begin(),data.end(),[& ](const Tuple& tup){return is_match< Pos ...>(tup,std :: forward< Args>(args)...);});
}


I would like to write function as this find:

multi_set<int, string, double, myType> m; //vector of tuples
m.insert(/*some data*/);
m.find<1,2>("something",2.123);

Or

m.find<0,3>(1,instanceOfMyType);
m.find<1>("somethingelse");

Where find can be parametrized corresponding to any subset of tuple parameters.

My code so far:

template <typename ... T>
class multi_set{
    typedef  tuple < T... > Tuple;
    vector<tuple<T...>> data = vector<tuple<T...>>();

public:
    void insert(T... t){
        data.push_back(tuple<T...>(t...));
    }


    template<size_t ... Pos>
    void find(???){
    // then I would like to use those params to search through data and 
    // return first matching item
    }
}

解决方案

// test whether a particular tuple is a match
template<size_t... Pos>
static bool is_match(const Tuple& tuple, const typename std::tuple_element<Pos, Tuple>::type &... args) {
    std::initializer_list<bool> results = { (std::get<Pos>(tuple) == args)... };
    return std::all_of(results.begin(), results.end(), [](bool p) { return p; });
}

// Find the first one that is a match.
template<size_t... Pos>
typename vector<Tuple>::const_iterator find(const typename std::tuple_element<Pos, Tuple>::type &... args) const {
    return std::find_if(data.begin(), data.end(), [&](const Tuple & tup) { return is_match<Pos...>(tup, args...); });
}

It's also possible to have find take a type parameter pack and perfectly forward, rather than taking fixed types with tuple_element. The benefit is that you can avoid an unnecessary conversion if == is transparent. The cost is that you can't take anything that can't be perfectly forwarded any more (e.g., braced initializer lists, 0 as a null pointer constant). A side benefit appears to be that MSVC 2013 doesn't choke on this version:

// test whether a particular tuple is a match
template<size_t... Pos, class... Args>
static bool is_match(const Tuple& tuple, Args&&... args) {
    std::initializer_list<bool> results = { (std::get<Pos>(tuple) == std::forward<Args>(args))... };
    return std::all_of(results.begin(), results.end(), [](bool p) { return p; });
}

// Find the first one that is a match.
template<size_t... Pos, class... Args>
typename vector<Tuple>::const_iterator find(Args&&... args) const {
    return std::find_if(data.begin(), data.end(), [&](const Tuple & tup) { return is_match<Pos...>(tup, std::forward<Args>(args)...); });
}

这篇关于模板函数以及元组类型的子集的相应参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆