C++17 折叠语法来测试向量组合
C++17 fold syntax to test vector composition
矢量的标准 C++17 实现 any
,all
:
template<class C, class T>
bool contains(const C& c, const T& value) {
return std::find(c.begin(), c.end(), value) != c.end();
}
template<class C, class... T>
bool any(const C& c, T&&... value) {
return (... || contains(c, value));
}
template<class C, class... T>
bool all(const C& c, T&&... value) {
return (... && contains(c, value));
}
用于
中的用法
std::array<int, 6> data0 = { 4, 6, 8, 10, 12, 14 };
assert( any(data0, 10, 55, 792));
assert( !any(data0, 11));
assert( all(data0, 6, 14, 8));
assert( !all(data0, 6, 7, 8));
是否有类似的方法来定义 only
,当且仅当向量的唯一值集与输入值匹配时,returns 为真?所以下面的断言将成立
std::array<int, 6> data1 = { 1, 1, 2, 1, 2 };
assert( only(data1, 1, 2));
assert( !only(data1, 1));
它不使用折叠表达式,但它应该可以工作
template<class C, class... T>
bool only(const C& c, T&& ...vals) {
auto ilist = {vals...}; //create initializer_list
for (auto el : c) {
if (!contains(ilist, el)) return false;
}
return true;
}
使用折叠表达式而不是 std::initializer_list
的内容
template<class T, class... Ts>
bool is_one_of(const T& val, Ts&& ...vals)
{
return ((val == vals) || ...);
}
template<class C, class... Ts>
bool only(const C& c, Ts&& ...vals)
{
for (const auto& el : c) {
if (!is_one_of(el, vals...)) return false;
}
return true;
}
// or if you hate raw loops
template<class C, class... Ts>
bool only(const C& c, Ts&& ...vals)
{
using std::beign; using std::end;
auto it = std::find_if(begin(c), end(c), [&](const auto& el) {
return !is_one_of(el, vals...);
});
return (it == end(c));
}
template<class C, class...Ts>
bool only( C const& c, Ts&&...ts ) {
std::size_t count = (std::size_t(0) + ... + contains(c, ts));
return count == c.size();
}
这会计算列表 ts...
中有多少在 c
中,如果您找到的数字等于 c
的元素,则 returns 为真。现在假设 c
和 ts
.
的唯一性
我们只是将计数移动到 only
并在标准算法中进行测试:
template<class C, class...Ts>
bool only( C const& c, Ts&&...ts ) {
using std::begin; using std::end;
auto count = std::count_if( begin(c), end(c), [&](auto&& elem) {
return ((elem == ts) || ...);
} );
return count == c.size();
}
鲍勃是你叔叔。
我们也可以做一个基于 notcontains
的 only
算法,但我认为那更复杂。
你可以提供一个count
函数:
template<class C, class T>
auto count(const C& c, const T& value) {
return std::count(c.begin(), c.end(), value);
}
然后这样写only
:
template<class C, class... T>
bool only(const C& c, T&&... value) {
return (count(c, value) + ...) == c.size();
}
这会处理 c
中的重复元素,但要求 value
是唯一的。
这里是 demo。
矢量的标准 C++17 实现 any
,all
:
template<class C, class T>
bool contains(const C& c, const T& value) {
return std::find(c.begin(), c.end(), value) != c.end();
}
template<class C, class... T>
bool any(const C& c, T&&... value) {
return (... || contains(c, value));
}
template<class C, class... T>
bool all(const C& c, T&&... value) {
return (... && contains(c, value));
}
用于
中的用法std::array<int, 6> data0 = { 4, 6, 8, 10, 12, 14 };
assert( any(data0, 10, 55, 792));
assert( !any(data0, 11));
assert( all(data0, 6, 14, 8));
assert( !all(data0, 6, 7, 8));
是否有类似的方法来定义 only
,当且仅当向量的唯一值集与输入值匹配时,returns 为真?所以下面的断言将成立
std::array<int, 6> data1 = { 1, 1, 2, 1, 2 };
assert( only(data1, 1, 2));
assert( !only(data1, 1));
它不使用折叠表达式,但它应该可以工作
template<class C, class... T>
bool only(const C& c, T&& ...vals) {
auto ilist = {vals...}; //create initializer_list
for (auto el : c) {
if (!contains(ilist, el)) return false;
}
return true;
}
使用折叠表达式而不是 std::initializer_list
template<class T, class... Ts>
bool is_one_of(const T& val, Ts&& ...vals)
{
return ((val == vals) || ...);
}
template<class C, class... Ts>
bool only(const C& c, Ts&& ...vals)
{
for (const auto& el : c) {
if (!is_one_of(el, vals...)) return false;
}
return true;
}
// or if you hate raw loops
template<class C, class... Ts>
bool only(const C& c, Ts&& ...vals)
{
using std::beign; using std::end;
auto it = std::find_if(begin(c), end(c), [&](const auto& el) {
return !is_one_of(el, vals...);
});
return (it == end(c));
}
template<class C, class...Ts>
bool only( C const& c, Ts&&...ts ) {
std::size_t count = (std::size_t(0) + ... + contains(c, ts));
return count == c.size();
}
这会计算列表 ts...
中有多少在 c
中,如果您找到的数字等于 c
的元素,则 returns 为真。现在假设 c
和 ts
.
我们只是将计数移动到 only
并在标准算法中进行测试:
template<class C, class...Ts>
bool only( C const& c, Ts&&...ts ) {
using std::begin; using std::end;
auto count = std::count_if( begin(c), end(c), [&](auto&& elem) {
return ((elem == ts) || ...);
} );
return count == c.size();
}
鲍勃是你叔叔。
我们也可以做一个基于 notcontains
的 only
算法,但我认为那更复杂。
你可以提供一个count
函数:
template<class C, class T>
auto count(const C& c, const T& value) {
return std::count(c.begin(), c.end(), value);
}
然后这样写only
:
template<class C, class... T>
bool only(const C& c, T&&... value) {
return (count(c, value) + ...) == c.size();
}
这会处理 c
中的重复元素,但要求 value
是唯一的。
这里是 demo。