我已经习惯了,std::tie没有多考虑它.它有效,所以我接受了:
auto test()
{
int a, b;
std::tie(a, b) = std::make_tuple(2, 3);
// a is now 2, b is now 3
return a + b; // 5
}
Run Code Online (Sandbox Code Playgroud)
但这个黑魔法是如何运作的呢?如何做一个临时的创建std::tie改变a和b?我发现这更有趣,因为它是一个库功能,而不是语言功能,所以我们可以自己实现并理解它.
在示例代码中
void foo()
{
static Bar b;
...
}
Run Code Online (Sandbox Code Playgroud)
使用GCC编译是否可以保证b以线程安全的方式创建和初始化?
在gcc的手册页中,找到了-fno-threadsafe-statics命令行选项:
不要发出额外的代码来使用C++ ABI中指定的例程来进行本地静态的线程安全初始化.您可以使用此选项在不需要线程安全的代码中略微减小代码大小.
这是否意味着,默认情况下,GCC的本地静态是线程安全的?所以没有理由明确保护,例如pthread_mutex_lock/unlock?
如何编写可移植代码 - 如何检查编译器是否会添加其防护?或者关闭GCC的这个功能是否更好?
我正在尝试这两种方法:
dispatch_async(dispatch_get_main_queue(),^{
[self handleClickAsync];
});
Run Code Online (Sandbox Code Playgroud)
和
[self performSelector:@selector(handleClickAsync) withObject:nil afterDelay:0];
Run Code Online (Sandbox Code Playgroud)
响应按钮按下.
第二个允许UIButton突出显示正如人们期望的那样并handleClickAsync在下一个运行循环中执行(我想:"以后某个时候"肯定).第一个不允许UIButton实例在操作完成之前点亮.
使用GCD执行此操作的正确方法是什么,或者performSelector仍然是唯一的方法?
我写过一本表现不佳的翻译,几周来一直在苦苦挣扎.在下面简单的bechmark
#include<stdio.h>
int main()
{
int x;
char buf[2048];
FILE *test = fopen("test.out", "wb");
setvbuf(test, buf, _IOFBF, sizeof buf);
for(x=0;x<1024*1024; x++)
fprintf(test, "%04d", x);
fclose(test);
return 0
}
Run Code Online (Sandbox Code Playgroud)
我们看到以下结果
bash-3.1$ gcc -O2 -static test.c -o test
bash-3.1$ time ./test
real 0m0.334s
user 0m0.015s
sys 0m0.016s
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,在添加"-std = c99"标志的那一刻,性能崩溃了:
bash-3.1$ gcc -O2 -static -std=c99 test.c -o test
bash-3.1$ time ./test
real 0m2.477s
user 0m0.015s
sys 0m0.000s
Run Code Online (Sandbox Code Playgroud)
我正在使用的编译器是gcc 4.6.2 mingw32.
生成的文件大约是12M,所以这两者之间的差异大约为21MB/s.
运行diff显示生成的文件是相同的.
我认为这与文件锁定有关fprintf,程序大量使用,但我无法找到在C99版本中关闭它的方法.
我尝试flockfile了在程序开始时使用的流,并funlockfile在最后使用了相应的流,但是遇到了关于隐式声明的编译器错误,以及声称对这些函数的未定义引用的链接器错误. …
我需要检查一下代码,Process.destroy()看看它kill在Linux上是一个什么样的子进程.
有谁知道这个方法的作用或链接到它的来源?我检查了jdk源代码,Process它只是一个抽象类,并且该destroy方法尚未实现,似乎没有链接到任何子类extends或者implements Process.任何帮助将不胜感激.
谢谢,
随着AVX的推出,英特尔将VEX编码方案引入了英特尔64和IA-32架构.该编码方案主要用于AVX指令.我想知道是否可以混合使用VEX编码指令和现在称为"传统SSE"的指令.
我问这个问题的主要原因是代码大小.请考虑以下两条说明:
shufps xmm0, xmm0, 0
vshufps xmm0, xmm0, xmm0, 0
Run Code Online (Sandbox Code Playgroud)
我通常使用第一个"广播"标量值到XMM寄存器中的所有位置.现在,指令集表明这两者之间的唯一区别(在这种情况下)是VEX编码的一个清除了YMM寄存器的高位(> = 128).假设我不需要,在这种情况下使用VEX编码版本有什么好处?第一条指令需要4个字节(0FC6C000),第二条指令需要5个(C5F8C6C000).
提前感谢所有答案.
我正在尝试实现一个库来读取Microsoft CFB(复合文件二进制)格式文件,根据该格式的官方规范.该规范可从该站点获得.
简而言之 - 文件的某些结构存储在一个红黑树中.我在用于在该树中存储这些结构的比较谓词时遇到问题.规范说,如果这些结构的名称(字符串存储为UTF-16,Windows API中的标准)不同,则必须遍历每个UTF-16代码点,并且:
(...)使用Unicode默认大小写转换算法,简单大小写转换变体(简单大小写折叠)转换为大写,并带有以下注释.<2>比较每个大写的UTF-16代码点二进制值.
该<2>基准说:
或Windows XP和Windows Server 2003:复合文件实现符合Unicode 3.0.1默认大小写转换算法,简单案例折叠(http://www.unicode.org/Public/3.1-Update1/CaseFolding-4.txt)除以下例外.
然而,当我查阅引用的案例折叠文件,并阅读那里引用的UTR#21"案例映射"时,我意识到案例折叠被定义为一种与下套管更相似的操作,而不是上部 -套管.
通过使用CaseFolding-4.txt,我们可以获得大写字母到小写字母的大小写折叠映射.映射始终为1对1,因为此处不需要完全折叠(扩展为多个字符的折叠).但是,小写字母到大写字母的反向映射不再是直截了当的.例如,
0392; C; 03B2; # GREEK CAPITAL LETTER BETA
03D0; C; 03B2; # GREEK BETA SYMBOL
Run Code Online (Sandbox Code Playgroud)
因此,我们无法知道是否03B2应转换为0392或03D0.标准是否定义了折叠成大写的东西?也许我应该使用case折叠,然后转换为大写?或者我完全错误地理解了规范?
我正在玩perl的rand(),并注意到当提供大于2 ^ 32的参数时,输出的最后几位变得可预测.
我发现说明它的最清晰的方法是使用以下脚本:
srand(); for $i (1..10) { printf "%4x\n",rand(2**48)%2**16 }
Run Code Online (Sandbox Code Playgroud)
每当我执行输出时
5101
6378
2a23
62f2
8d15
effc
9657
2d16
f669
40c0
Run Code Online (Sandbox Code Playgroud)
(这不只是前10个值,但我没有看到复制一长串"随机"数字的观点)
对srand()的调用是多余的,但它可以很容易地提供一个参数,并且看到它不会改变任何东西.
我试过这个:
我知道rand()不应该是加密安全的,但是可预测的最后16位比我理解的更糟糕.我使用的任何功能都错了吗?
我正在编写一个可以与音频CD和混合CD一起使用的应用程序.我想有一种方法来确定当前在应用程序使用的驱动器中是否存在音频或混合类型(具有至少一个音轨)光盘.
到目前为止,我能够确定驱动器是CD-ROM GetDriveType.但是,事实证明,识别驱动器内部的媒体并不容易.这是我到目前为止所得到的:
int drive_has_audio_disc(const char *root_path)
{
char volume_name[MAX_PATH+1];
BOOL winapi_rv;
DWORD fs_flags;
int rv;
winapi_rv = GetVolumeInformation(root_path, volume_name, sizeof(volume_name),
NULL, NULL, &fs_flags, NULL, 0);
if(winapi_rv != 0)
{
rv = (strcmp(volume_name, "Audio CD") == 0 &&
(fs_flags & FILE_READ_ONLY_VOLUME));
}
else
{
rv = (GetLastError() == ERROR_INVALID_PARAMETER) ? 0 : -1;
}
return rv;
}
Run Code Online (Sandbox Code Playgroud)
但是,它依赖于Windows为所有被识别为音频的光盘分配名称"Audio CD"的事实.这感觉不对,并且在混合模式CD上会失败,因为它们在Windows中的名称由数据轨道的卷名决定.此外,else块在这里是因为我注意到GetVolumeInformation返回错误,GetLastError等于ERROR_INVALID_PARAMETER驱动器中根本没有光盘.
理想情况下,我正在寻找类似CDROM_DISC_STATUSLinux上的ioctl之类的东西.它返回CDS_NO_INFO,CDS_AUDIO,CDS_MIXED,或者一些其他值,具体取决于光盘的内容.
有没有其他办法处理这个?那么混合模式光盘呢?
说我有这段代码.
#include <string>
int main()
{
std::string(0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
写入std::string(0)结果std::basic_string<char>::basic_string(const char*)被调用,0作为此构造函数的参数,尝试将参数视为指向C字符串的指针.
运行此代码显然会导致std::logic_error被抛出.但我的问题是:为什么GCC和MSVC 8.0都没有发出任何警告?我希望看到"从没有强制转换的整数制作指针"这一行.
ctimemanbook 页面说POSIX.1-2008标记了这个函数(在其他一些函数中)也是过时的,并建议strftime应该使用它.我想知道格式字符串是如何strftime看起来以获得相同的输出ctime.
到目前为止%a %b %_2d %T %Y%n,我唯一得到的是,但它%_2d是一个Glibc扩展,我也希望在Windows上工作.
这两个声明有什么区别?
class foo
{
public:
static void bar();
};
Run Code Online (Sandbox Code Playgroud)
和
namespace foo
{
void bar();
}
Run Code Online (Sandbox Code Playgroud)
我看到它的方式,没有,因为barin class foo无法访问this,也没有bar命名空间foo.
当然,这纯粹是理论上的.
我正在为一个类编写一个编译器,而且我坚持使用GNU的语法进行间接调用.考虑这个简单的程序:
.text
.globl main
main:
movl func, %eax
call *%eax
ret
func:
movl $42, %eax
ret
Run Code Online (Sandbox Code Playgroud)
使用gcc -m32 -O0并运行生成的程序会给我一个分段错误.谁能告诉我如何正确地进行通话?
谢谢.
文森特.