对于线程安全的延迟初始化,是否应该更喜欢函数内部的静态变量,std :: call_once或显式双重检查锁定?有什么有意义的差异吗?
在这个问题中可以看到这三个.
C++ 11中的Double-Checked Lock Singleton
在Google中出现了两个版本的C++ 11双重检查锁定版本.
Anthony Williams 使用显式内存排序和std :: call_once 显示双重检查锁定.他没有提到静态,但该文章可能是在C++ 11编译器可用之前编写的.
杰夫Preshing,在广泛的书面记录,描述了双重检查锁定的几个变化.他确实提到使用静态变量作为选项,他甚至表明编译器将生成用于双重检查锁定的代码以初始化静态变量.我不清楚他是否认为一种方式比另一种更好.
我觉得这两篇文章都是教学的,没有理由这样做.如果您使用静态变量或std :: call_once,编译器将为您执行此操作.
我刚注意到了
http://en.cppreference.com/w/cpp/error/uncaught_exception
C++ 17将替换std::uncaught_exception()
,返回a bool
,with std::uncaught_exceptions()
,返回一个int
.
描述这个的标准的补充在这里:
http://isocpp.org/files/papers/n4259.pdf
它没有提供理由,但确实如此
[注意:当uncaught_exceptions()> 0时,抛出异常会导致调用std :: terminate()(15.5.1). - 结束说明]
这是奇怪的模糊.
这种变化的原因是什么?在C++ 17或标准的某些未来版本中,是否可以有多个活动异常?
问题
对于用户定义类型的std :: unordered_map或std :: unordered_set的第三个模板参数,std :: hash有什么好的特殊性,所有成员数据类型都已经具有良好的std :: hash特性?
对于这个问题,我将"好"定义为易于实现和理解,合理有效,并且不太可能产生哈希表冲突.商品的定义不包括任何有关安全性的陈述.
什么是谷歌的状态
目前,两个StackOverflow问题是Google搜索"std hash specialization"的第一个问题.
第一个,如何在无序容器中为用户定义的类型专门化std :: hash :: operator()?,解决了打开std命名空间和添加模板特化是否合法的问题.
第二个,如何专门化来自其他库的类型的std :: hash,基本上解决了同样的问题.
这留下了当前的问题.鉴于C++标准库的实现为标准库中的基本类型和类型定义了散列函数,为用户定义的类型专门化std :: hash的简单有效方法是什么?有没有一种很好的方法来组合标准库实现提供的哈希函数?
(编辑感谢dyp.)StackOverflow的另一个问题是如何组合一对哈希函数.
谷歌的其他结果没有任何帮助.
这篇 Dobbs博士的文章指出,两个令人满意的哈希的XOR将产生一个新的令人满意的哈希值.
这篇文章似乎是从知识中说出并暗示了很多东西,但却注重细节.它与第一个例子中的简短评论中的Dr. Dobbs文章相矛盾,称使用XOR组合散列函数会产生一个弱的结果散列函数.
因为XOR应用于任何两个相等的值导致0,我可以看出为什么XOR本身很弱.
元问题
一个很好的理由回答解释为什么这个问题无效且一般无法回答也是受欢迎的.
使用std::map
或时std::unordered_map
,访问可能不在容器中的元素的首选方法是什么?如果有人请求许可或要求宽恕吗?为什么?
那是,
if (mymap.find(key) != mymap.end()) {
value = mymap.at(key);
// do stuff
}
else {
// do something else
}
Run Code Online (Sandbox Code Playgroud)
与
try {
value = mymap.at(key);
// do stuff
}
catch(const std::out_of_range& oor) {
// do something else
}
Run Code Online (Sandbox Code Playgroud) 模块加载如何在CPython下工作?特别是,用C编写的扩展的动态加载如何工作?我在哪里可以了解到这一点?
我发现源代码本身相当压倒性.我可以看到,可靠的ol' dlopen()
和朋友用在支持它的系统上但没有任何大局观,从源代码中解决这个问题需要很长时间.
关于这个主题可以写很多,但据我所知,几乎没有任何内容 - 描述Python语言本身的大量网页使搜索变得困难.一个很好的答案将提供一个相当简短的概述和参考资源,我可以了解更多.
我最关心的是它是如何在类Unix系统上运行的,因为这就是我所知道的但我感兴趣的是如果这个过程在其他地方类似.
为了更具体(但风险假设太多),CPython如何使用模块方法表和初始化函数来"理解"动态加载的C?
python cpython dynamic-loading python-import python-internals
TC对这个问题的回答留下了一个有趣的评论:
TC说:
有"标题",还有"源文件"."标题"不需要是实际文件.
这是什么意思?
仔细阅读标准,我看到对"头文件"和"标题"的大量引用.但是,关于#include
,我注意到该标准似乎引用了"标题"和"源文件 ".(C++ 11,§16.2)
A preprocessing directive of the form
# include < h-char-sequence> new-line
searches a sequence of implementation-defined places for a header identified uniquely
by the specified sequence between the < and > delimiters, and causes the replacement
of that directive by the entire contents of the header. How the places are specified
or the header identified is implementation-defined.
Run Code Online (Sandbox Code Playgroud)
和
A preprocessing directive of the form
# include " q-char-sequence" …
Run Code Online (Sandbox Code Playgroud) 干杯和hth.- Alf在这个答案中发表评论说,与C++ 98相比,值初始化可以说是C++ 03的一个新特性.我想知道他的意思.
是值初始化的C++ 98的一部分?它是出现在概念中而不是名义上吗?为什么它被添加到C++ 03标准中?
我有'03标准的副本,但不是'98标准.这是默认初始化和值初始化的定义.
默认初始化T类型的对象意味着:
- 如果T是非POD类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
- 如果T是数组类型,则每个元素都是默认初始化的;
- 否则,对象被零初始化.
对值类型T的对象进行值初始化意味着:
- 如果T是具有用户声明的构造函数(12.1)的类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
- 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的;
- 如果T是数组类型,则每个元素都是值初始化的;
- 否则,对象被零初始化
我的猜测是'98有默认初始化但不是值初始化,并且两者之间存在一些关键差异.说实话,我在解析这里的标准时遇到了麻烦,我不明白这些定义之间的区别.
我最近看到一些好奇的东西.在HHVM源代码中,该main()
函数的前3行内容如下:
if (!argc) {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这有点傻,但是,我还是忍不住想知道...... 为什么要回归0!并不是我认为有一些正确的方法可以解决这个问题,但通常与成功相关的0返回似乎特别不合适.
除了没有崩溃,有没有一个适当的响应argc
0?(甚至还不到0?)这有关系吗?
我知道最终在argc
0 的情况下结束的唯一方法是exec()
和朋友一起.如果出于某种原因确实发生了这种情况,那几乎可以肯定是调用者中的一个错误,而被调用者无法做很多事情.
(标记为C和C++,因为我希望这两种语言的答案是相同的)
编辑:为了使问题不那么模糊和哲学,我会提供另一种选择.
if (!argc) {
puts("Error: argc == 0");
return 1;
}
Run Code Online (Sandbox Code Playgroud)
关键点是有错误的指示并返回非零值.这种情况极不可能需要,但如果是这样,你可能会尝试指出错误.另一方面,如果检测到的错误严重到argc
等于0,那么尝试访问stdout或C标准库可能是不好的.
我正在尝试创建一个constexpr函数,它将连接Xeo的以下答案来连接任意数量的char数组,它连接两个char数组.
#include <array>
template<unsigned... Is> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};
template<unsigned N1, unsigned... I1, unsigned N2, unsigned... I2>
constexpr std::array<char const, N1+N2-1> concat(char const (&a1)[N1], char const (&a2)[N2], seq<I1...>, seq<I2...>){
return {{ a1[I1]..., a2[I2]... }};
}
template<unsigned N1, unsigned N2>
constexpr std::array<char const, N1+N2-1> concat(char const (&a1)[N1], char const (&a2)[N2]){
return concat(a1, a2, gen_seq<N1-1>{}, gen_seq<N2>{});
}
Run Code Online (Sandbox Code Playgroud)
我到目前为止的尝试:
#include <iostream>
#include <array>
template<unsigned... Is> struct seq{}; …
Run Code Online (Sandbox Code Playgroud) 目前,boost::optional<>
支持引用,但std::experimental::optional<>
libstdc ++中的我的系统不支持.这是否反映了可能使其成为标准的内容?
我知道可选提案作者将可选引用作为单独的提案分离出来,以便主要的可选提案更有可能被接受.关于可选参考文献的提案是否被拒绝或是否已停止工作?