我的一个朋友和我正在讨论什么是JS的封闭,什么不是.我们只是想确保我们真正理解它.
我们来看看这个例子吧.我们有一个计数循环,并希望在控制台上打印计数器变量延迟.因此,我们使用setTimeout
和闭包来捕获计数器变量的值,以确保它不会打印值N的N倍.
错误的解决方案,无需关闭或接近任何倒闭将是:
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
这当然会打印10次i
循环后的值,即10.
所以他的尝试是:
for(var i = 0; i < 10; i++) {
(function(){
var i2 = i;
setTimeout(function(){
console.log(i2);
}, 1000)
})();
}
Run Code Online (Sandbox Code Playgroud)
按预期打印0到9.
我告诉他,他并没有使用封闭捕获i
,但他坚持认为他是.我证明他没有使用闭包,将for循环体放在另一个setTimeout
(将他的匿名函数传递给setTimeout
),再次打印10次10.如果我将他的函数存储在a中var
并在循环之后执行它同样适用,也打印10次10.所以我的论点是他并没有真正捕获它的值i
,使他的版本不是一个闭包.
我的尝试是:
for(var i = 0; i < …
Run Code Online (Sandbox Code Playgroud) 我正在INSERT ... ON DUPLICATE KEY UPDATE
为PRIMARY KEY
下表中的a 做一个:
DESCRIBE users_interests;
Run Code Online (Sandbox Code Playgroud)
+------------+---------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------+------+-----+---------+-------+
| uid | int(11) | NO | PRI | NULL | |
| iid | int(11) | NO | PRI | NULL | |
| preference | enum('like','dislike','ignore') | YES | | NULL | |
+------------+---------------------------------+------+-----+---------+-------+
Run Code Online (Sandbox Code Playgroud)
但是,即使这些值应该是唯一的,我也会看到2行受到影响.
INSERT INTO users_interests (uid, iid, preference) VALUES (2, 2, 'like')
ON DUPLICATE KEY UPDATE …
Run Code Online (Sandbox Code Playgroud) 考虑我有一个自定义类型(我可以扩展):
struct Foo {
int a;
string b;
};
Run Code Online (Sandbox Code Playgroud)
如何将此对象的实例分配给a std::tie
,即std::tuple
引用?
Foo foo = ...;
int a;
string b;
std::tie(a, b) = foo;
Run Code Online (Sandbox Code Playgroud)
尝试失败:
tuple<int&,string&> = Foo
由于赋值运算符是必须是左侧对象成员的二元运算符之一,因此无法重载赋值运算符.
所以我试图通过实现一个合适的元组转换运算符来解决这个问题.以下版本失败:
operator tuple<int,string>() const
operator tuple<const int&,const string&>() const
它们导致赋值错误,告诉" operator =
没有超载tuple<int&,string&> = Foo
".我想这是因为"转换为任何类型的X +推导模板参数X for operator ="不能同时工作,只能同时使用其中一个.
不完美的尝试:
因此,我尝试为绑定的确切类型实现转换运算符:
现在分配工作,因为类型现在(转换后)完全相同,但这不适用于我想支持的三种情况:
int a;
为long long a;
客户端),则失败,因为类型必须完全匹配.这与将元组分配给允许可转换类型的引用元组的通常用法相矛盾.(1)不,我不想使用ncurses,因为我想了解终端是如何工作的,并且可以自己编程.:)它不必是可移植的,它只能在基于linux xterm的终端模拟器上工作.
我想要做的是编写一个交互式终端应用程序,如htop和vim.我的意思不是字符的输出看起来像盒子或设置颜色,这是微不足道的; 还要使内容适合窗口大小.我需要的是
如何进行鼠标交互,比如单击一个字符并滚动鼠标滚轮(当鼠标处于特定字符时)以实现滚动[ 编辑:当然在终端模拟器中 ],以及
如何完全保存和恢复父进程的输出并从输出中分离我的打印,所以在离开我的应用程序后,我在shell中输入的命令应该在那里,就像运行htop并再次退出时一样:什么都看不见从这个应用程序.
我真的不想使用ncurses.但是,当然,如果您知道ncurses的哪一部分负责这些任务,欢迎您告诉我在源代码中我可以找到它,所以我将研究它.
(如果您是C++ 11专业版,请跳到粗体段.)
假设我想编写一个模板方法,该方法调用并返回传递对象的结果,该对象的类型是模板参数:
template<ReturnType, T>
ReturnType doSomething(const T & foo) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
Run Code Online (Sandbox Code Playgroud)
所以T
必须有一个方法ReturnType T::bar() const
才能在这样的调用中使用:
struct MyClass {
...
int bar() const;
...
};
...
MyClass object;
int x = doSomething<int, MyClass>(object);
Run Code Online (Sandbox Code Playgroud)
MyClass
感谢类型扣除,我们无需写信,调用成为:
int x = doSomething<int>(object);
Run Code Online (Sandbox Code Playgroud)
但是省略<int>
也会导致编译错误,因为该方法不需要返回int以便x
以后分配(char
例如,它可以返回).
在C++ 0X/11,我们有auto
和decltype
,使我们可以用它来推断模板方法的返回类型:
template<T>
auto doSomething(const T & foo) -> decltype(foo.bar()) {
return foo.bar(); // …
Run Code Online (Sandbox Code Playgroud) QPainter
a 绘制街道地图widget
QPainterPaths
它制作包含预先绘制的路径widget
目前是QWidget
,不是QGLWidget
,但这可能会改变.QImage
绘制成a 并最终将所有图像绘制到widget
QPainterPaths
已经分块了,所以这不是问题QImages
约5倍QWidget
QPainterPaths
,每个有大约150个线性线段QPainter::Antialiasing
渲染提示绘制大约15k路径,QPen
使用圆顶和圆形连接QPainterPaths
(和线宽+颜色;一些绘制,一些填充)
QPainter
支持QPainterPaths
转换为可以在a上绘制的其他东西OpenGL buffer
,这将是一个很好的解决方案.OpenGL
屏幕外渲染,我知道有不同类型的OpenGL缓冲区,其中大多数不是用于2D图像渲染而是用于顶点数据.Paint Device for chunk | Rendering the chunk itself | Painting chunk on QWidget
-----------------------+----------------------------+--------------------------
QImage | 2000 ms | < …
Run Code Online (Sandbox Code Playgroud) 编辑,为了避免混淆:
decltype
不不接受两个参数.看到答案.
以下两个结构可用于T
在编译期间检查类型上成员函数的存在性:
// Non-templated helper struct:
struct _test_has_foo {
template<class T>
static auto test(T* p) -> decltype(p->foo(), std::true_type());
template<class>
static auto test(...) -> std::false_type;
};
// Templated actual struct:
template<class T>
struct has_foo : decltype(_test_has_foo::test<T>(0))
{};
Run Code Online (Sandbox Code Playgroud)
我认为这个想法是在检查成员函数的存在时使用SFINAE,因此如果p->foo()
无效,则只test
返回返回的省略号版本std::false_type
.否则,第一个方法被定义T*
并将返回std::true_type
.实际的"切换"发生在第二个类中,它继承自返回的类型test
.与不同的方法相比,这看起来更聪明,更"轻巧" is_same
.
在decltype
与两个参数第一次看令我感到诧异,因为我认为这只是得到一个表达式的类型.当我看到上面的代码时,我认为它类似于"尝试编译表达式并始终返回第二种类型.如果表达式无法编译则失败"(所以隐藏此专业化; SFINAE).
但:
然后我想我可以使用这个方法来编写任何"is valid expression"检查器,只要它依赖于某种类型T
.例:
...
template<class T>
static auto test(T* p) -> decltype(bar(*p), std::true_type());
...
Run Code Online (Sandbox Code Playgroud)
这一点,所以我想,将返回 …
从下面的代码sizeof(Base) == 24
和sizeof(Derived) == 24
.
为什么他们的尺寸相同?
在Base
课堂上我们有3名成员,在Derived
课堂上我们有另一名成员.
class Base
{
private:
double d;
protected:
long l;
public:
int i;
};
class Derived : public Base
{
private:
float f;
};
Run Code Online (Sandbox Code Playgroud) 的备用屏幕用于通过像vim,HTOP,屏幕,alsamixer中,以下,...它像一个不同缓冲液中的终端的内容的,其消失的应用程序退出时,所以整个终端许多"用户交互式"应用终端恢复,看起来应用程序没有输出任何东西.
我想在我自己的shell(bash)脚本中实现完全相同的东西,除了它不必是可移植的.我坚持只使用linux和基于xterm的终端模拟器; 但解决方案应该使用像tput
是否可能的东西.但是,我不想使用某些外部脚本语言(甚至是类似C的东西).
虽然我不想使用C(因为它应该是尽可能少的依赖项的bash脚本),但我查看了较少的源代码.它似乎使用terminfo作为数据库,并在其初始化中查找"ti"终端功能.删除行时,它不使用备用的sceen,所以我假设我找到了负责的代码行.
但是,我找不到这样的能力man terminfo
.但也许我在错误的道路上寻找解决方案.也许terminfo/tput不是我的朋友.
那么(如何)我可以在bash脚本中使用备用屏幕?有人知道一个简单的应用程序,我可以在其中找到源代码提示吗?(C应用程序或bash脚本或其他......)
我有一个自定义容器类和定义的迭代器,所以我可以这样做:
for (auto i : c)
Run Code Online (Sandbox Code Playgroud)
但有反向迭代的东西吗?
就像是:
for_reverse (auto i : c)
Run Code Online (Sandbox Code Playgroud)