模板函数以及元组类型的子集的相应参数 [英] template function with corresponding parameters to subset of tuple types
问题描述
我想像这样写:
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屋!