- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用最新的 clang++ 在 c++17 中使用折叠表达式。我尝试使用它为数组实现 less 运算符,我想将其用于固定大小的字符串。
这是我到达的地方。有没有更好的方法来做到这一点,尤其是避免在表达式中分配索引?
使用“clang++ test_fold_expr_less.cpp -o test_fold_expr_less -std=c++1z”编译它,输出在这里。
prompt$ ./test_fold_expr_less
=== less ===
0
1
0
0
1
0
0
0
0
1
1
1
#include <iostream>
#include <utility>
std::uint64_t arr1[8] = {1, 7, 2, 4, 8, 9, 3, 6};
std::uint64_t arr2[8] = {1, 7, 2, 4, 8, 9, 3, 6};
std::uint64_t arr3[8] = {1, 7, 2, 5, 8, 9, 3, 6};
std::uint64_t arr4[8] = {1, 7, 2, 3, 8, 9, 3, 6};
struct less_t
{
template < typename T, std::size_t N, std::size_t... I >
bool impl(T const (& lhs)[N], T const (& rhs)[N], std::index_sequence < I... >) const
{
std::size_t i{0};
if (((i = I, (lhs[I] < rhs[I]) ? true : lhs[I] != rhs[I]) || ...))
return lhs[i] < rhs[i];
else
return false;
}
template < typename T, std::size_t N >
bool operator () (T const (& lhs)[N], T const (& rhs)[N]) const
{
return impl(lhs, rhs, std::make_index_sequence < N >());
}
};
int main()
{
std::cout << "=== less ===" << std::endl;
less_t const less{};
std::cout << less(arr1, arr2) << std::endl;
std::cout << less(arr1, arr3) << std::endl;
std::cout << less(arr1, arr4) << std::endl;
std::cout << less(arr2, arr1) << std::endl;
std::cout << less(arr2, arr3) << std::endl;
std::cout << less(arr2, arr4) << std::endl;
std::cout << less(arr3, arr1) << std::endl;
std::cout << less(arr3, arr2) << std::endl;
std::cout << less(arr3, arr4) << std::endl;
std::cout << less(arr4, arr1) << std::endl;
std::cout << less(arr4, arr2) << std::endl;
std::cout << less(arr4, arr3) << std::endl;
}
最佳答案
我将从一些关于折叠表达式的使用的观察和假设开始。
本质上,我们想通过一个折叠表达式来编写字典顺序比较。一旦我们可以确定结果,我们就想摆脱比较。使用一元左折叠
(... OP comparison)
评估为
( ( (comparison(0) OP comparison(1)) OP comparison(2) )... )
不评估 comparison(I)
的唯一方法在之前执行的其中一个比较中抛出异常并且短路。我不认为在这里使用异常是个好主意。所以我会尝试短路。这需要 OP
要么是||
或 &&
, 左边的表达式必须求值为 bool 值,告诉计算是否继续:
( ( (comparison(0) && comparison(1)) && comparison(2) )... )
comparison(N) -> bool // continue?
在字典序比较中,我们继续评估 lhs 和 rhs 的当前元素是否相等。所以 comparison(I)
的值必须是 lhs[I] == rhs[I]
:
#define comparison(I) (lhs[I] == rhs[I])
然后整个折叠表达式的结果告诉我们两个序列是否完全相等:
auto equal = (... && comparison(I));
但是,通过这样做,我们丢失了有关 lhs[I] < rhs[I]
是否存在的信息。或 lhs[I] > rhs[I]
是我们停止比较的原因。我们可以使用副作用从表达式中获取此信息:
#define comparison(I) (less = lhs[I] < rhs[I], lhs[I] == rhs[I])
bool less;
auto equal = (... && comparison(I));
此时,我们知道equal == true
或者我们可以使用最后存储到 less
的值确定总体结果:
return !equal && less;
(如果 lhs == rhs
那么 !(lhs < rhs)
,那么我们返回 false。否则,我们返回 lhs != rhs
并且我们使用存储在 less
中的结果。因此,如果我们有 at,则不需要初始化 less
数组中至少有一个元素。)
还有改进的余地:我们可以执行分配给less
, 以及 lhs[I] < rhs[I]
的值计算只有当我们需要的时候,也就是只有当lhs[I] != rhs[I]
.使用另一个短路:
#define comparison(I) (lhs[I] == rhs[I] || (less = lhs[I] < rhs[I], false))
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我认为这很神秘。划线部分的值始终为false
由于使用了逗号表达式。自 false
是 ||
的中性元素, 整体|| (..)
仅执行副作用但不更改 comparison(I)
的值, 但只有在 ||
的左侧才会执行此副作用产量 false
.
最后一个改进可以通过认识到如果我们从不分配给 less
来实现,我们知道 lhs == rhs
我们可以返回 false
.
结合起来,我们得到:
bool less = false;
auto equal = (... && (lhs[I] == rhs[I] || (less = lhs[I] < rhs[I], false)));
(void)equal; // we don't need you
return less;
完整示例:
#include <iostream>
#include <utility>
struct loud
{
std::uint64_t v;
loud(int x) : v(x) {}
static auto& opEqual() { static int v = 0; return v; }
static auto& opLess() { static int v = 0; return v; }
friend bool operator==(loud l, loud r) { return opEqual()++, l.v == r.v; }
friend bool operator<(loud l, loud r) { return opLess()++, l.v < r.v; }
static void print_stats(std::ostream& o) {
o << "operator< " << opLess() << " operator== " << opEqual();
}
static void reset_stats() {
opEqual() = opLess() = 0;
}
};
loud arrs[][8] = {
{1, 7, 2, 4, 8, 9, 3, 6}
,{1, 7, 2, 4, 8, 9, 3, 6}
,{1, 7, 2, 5, 8, 9, 3, 6}
,{1, 7, 2, 3, 8, 9, 3, 6}
};
struct less_t
{
template < typename T, std::size_t N, std::size_t... I >
bool impl(T const (& lhs)[N], T const (& rhs)[N], std::index_sequence < I... >) const
{
bool less = false;
auto equal = (... && (lhs[I] == rhs[I] || (less = lhs[I] < rhs[I], false)));
(void)equal; // we don't need you
return less;
}
template < typename T, std::size_t N >
bool operator () (T const (& lhs)[N], T const (& rhs)[N]) const
{
return impl(lhs, rhs, std::make_index_sequence < N >());
}
};
template<class T, int N>
void test(T const (&lhs)[N], T const (&rhs)[N])
{
auto const stdres = std::lexicographical_compare(lhs, lhs+N, rhs, rhs+N);
loud::reset_stats();
auto const foldres = less_t{}(lhs, rhs);
std::cout << (stdres == foldres) << " -- ";
loud::print_stats(std::cout);
std::cout << "\n";
}
int main()
{
std::cout << std::boolalpha;
std::cout << "=== less ===" << std::endl;
for(auto& lhs : arrs)
for(auto& rhs : arrs)
test(lhs, rhs);
}
输出——注意我不打印折叠表达式函数的结果,但我将该结果与 std::lexicographical_compare
的结果进行比较. true
因此意味着两种算法产生相同的结果。
=== less ===
true -- operator< 0 operator== 8
true -- operator< 0 operator== 8
true -- operator< 1 operator== 4
true -- operator< 1 operator== 4
true -- operator< 0 operator== 8
true -- operator< 0 operator== 8
true -- operator< 1 operator== 4
true -- operator< 1 operator== 4
true -- operator< 1 operator== 4
true -- operator< 1 operator== 4
true -- operator< 0 operator== 8
true -- operator< 1 operator== 4
true -- operator< 1 operator== 4
true -- operator< 1 operator== 4
true -- operator< 1 operator== 4
true -- operator< 0 operator== 8
关于c++ - 使用折叠表达式为数组实现 less 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31274365/
我需要能够在我的 javascript 中折叠/折叠各种代码片段,有点像 C# 中的#region #endregion。我找不到执行此操作的方法,有什么帮助吗? 最佳答案 窗口菜单 -> 选择首选项
折叠 Accordion 时,我注意到在这段时间内没有显示边框。例如,当 Accordion 展开时,我们会在展开时看到边界。这也可以在折叠 Accordion 时完成吗? Accordion 折叠时
是否有任何插件或快捷方式可以隐藏 Sublime Text 2 中除代码部分之外的所有内容? 我需要一次折叠除部分之外的所有部分,而不是一次折叠一个部分。 谢谢~ 最佳答案 如果将鼠标悬停在行号上,您
在 Web 应用程序中,我有一个操作可能会以各种不同的方式失败,或者最终会成功。 在这种情况下,成功和失败由 SimpleResult 的子类表示(表示 HTTP 响应) 我使用 scalaz/上的
我的数据在这样的分组方案中分为三个连续的类别: 因此,整个“OCM”组被分解为名为“N/A”、“Financials”、“Industrials”等的子组,每个子组又被分解为进一步的子组。 我在 Ex
我正在尝试猫图书馆,但我很难在我应该导入和创建的东西之间导航。我的问题如下: sealed trait Checks case class CheckViolation(id: Long, msg:
有没有办法查看当前文件中打开的折叠位置? 我个人在打开折叠和移动时遇到问题,我无法找到折叠开始的线!也许有一个选项可以在数字旁边设置一个漂亮的折叠提示。也许是这样的: + 1 void myfunc(
我正在寻找一种按空白深度折叠纯文本的方法。我更喜欢 Notepad++ 解决方案,但如果它只能在另一个编辑器中完成,我可以处理。例如 Header is arbitrary text Child i
今天早上我遇到了优秀的 jstree jQuery UI 插件。一句话——太棒了!它易于使用,易于样式化,并且可以按照包装盒上的说明进行操作。我还没有弄清楚的一件事是 - 在我的应用程序中,我想确
我有以下XAML,其中堆叠了三个组框。这些组框的标题中是复选框。 我想要实现的是:当我选中/取消选中一个框时,我希望相应的groupbox能够以平滑的动画缓慢展开/折叠。 我正在Blend 4中尝试此
我知道如何使用 zO 打开光标下的所有折叠. 但是反向怎么做呢? 我想要类似 za 的东西确实如此,但也具有递归性。 附注。我知道有 zC ,但它会关闭与当前行相关的所有父级折叠,我想关闭子级。 最佳
我试图防止点击 About Us 时导航栏崩溃部分或 Projects以下代码中的部分。我已经尝试过event.stopPropagation()在这两个按钮上,但是当 jQuery 代码执行时,导航
我有一个DataGrid。它具有DataGrid.RowDetailsTemplate。当单击一个按钮时,它应该展开/折叠;我该怎么做?
我有一个 Storyboard动画,使用Opacity属性可以使控件淡出 View 。完成后,我想将控件的“可见性”设置为“折叠”。 我也想做相反的事情...将“可见性”设置为“可见”,然后使用 St
我将 SublimeText3 用于 C++ 和 Java。我想知道是否有办法折叠文件/类中的所有方法,然后将它们全部展开,而不管插入符号在哪里。或者有没有办法列出所有的功能/方法。 基本上我希望能够
如何在 YAML 中断开长字符串(如长 url 或文件名/路径),而不会将换行符变成空格? 示例输入: url: > https://example.com/?what=Lorem %20ip
给定: import shapeless._ case class F(x: Option[Int], y: Option[Int]) 我想帮忙写一个函数,f: def f(Option[Int]::
我想测试数组是否仅包含唯一元素,我的解决方案如下: function uniqueElements(a) { var r = true; while (a) { var [el, a]
我试图在单击“项目”按钮时使“javascript 项目”和“CGI 项目”滑动切换。但是,我不太明白为什么点击时只有CGI项目按钮切换,而javascript项目按钮保持不变? 我正在尝试使用 Jq
我有一组需要在 UI 中显示的项目,例如标题和其下的项目列表。 有一个父组件,我将在其中将此数据传递到如下所示的文件. 在此基础上显示了父子布局。 现在我需要根据标题的点击展开/折叠。 有一个可以附加
我是一名优秀的程序员,十分优秀!