Alb*_*lby 9 c++ tuples subset variadic-templates c++11
我想写这个函数find
:
multi_set<int, string, double, myType> m; //vector of tuples
m.insert(/*some data*/);
m.find<1,2>("something",2.123);
Run Code Online (Sandbox Code Playgroud)
要么
m.find<0,3>(1,instanceOfMyType);
m.find<1>("somethingelse");
Run Code Online (Sandbox Code Playgroud)
哪里find
可以参数化对应于元组参数的任何子集.
我的代码到目前为止:
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
}
}
Run Code Online (Sandbox Code Playgroud)
// 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...); });
}
Run Code Online (Sandbox Code Playgroud)
也可以find
采用类型参数包并完美地向前,而不是采用固定类型tuple_element
.好处是,如果==
透明,您可以避免不必要的转换.成本是你不能再采取任何不能完美转发的东西(例如,支撑的初始化列表,0
作为空指针常量).附带好处似乎是MSVC 2013不会阻止此版本:
// 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)...); });
}
Run Code Online (Sandbox Code Playgroud)