我正在阅读C++ 11标准,但无法弄清楚是否
T x{};
Run Code Online (Sandbox Code Playgroud)
是值初始化或默认初始化(自动存储).它确实说得非常清楚:
10一个对象,其初始化程序是一组空的括号,即(),应进行值初始化.
然后
11如果没有为对象指定初始值设定项,则默认初始化该对象;
但我能找到的T x{};是:
在表格T x(a)中发生的初始化; T x {a}; 以及在新表达式(5.3.4)中,static_cast表达式(5.2.9),函数表示法类型转换(5.2.3)以及基本和成员初始化器(12.6.2)称为直接初始化.
和
如果初始化程序是(非括号的)braced-init-list,则对象或引用是列表初始化的(8.5.4).
我很想进入阅读标准的水平.有人能指出我正确的方向吗?
这个问题直接来自Cracking the Coding Interview,4th Ed,所以我不是百分百肯定我可以在这里发布; 如果没有,请告诉我,我会删除它.
问题5.7:
数组A [1..n]包含从0到n的所有整数,但缺少一个数字.在这个问题中,我们无法通过单个操作访问A中的整个整数.A的元素被表示为二进制的,我们可以用它来访问他们的唯一操作是"取A [1]的第j个比特",这需要一定的时间.编写代码以查找缺少的整数.你能在O(n)时间做吗?
我知道如何解决这个问题.我不明白的是她是如何解决的.她的方法:
我可以看到这种方法在n为某些正m的形式(2 ^ m)-1时有效...但是在一般情况下看不出它是如何工作的.
考虑二进制基数中的自然数.然后第i个最小sig位的序列如下:
然后,对于某些s,最sig位具有一些序列{(s)0(s)1} .如果n =(2 ^ m)-1,那么一切都很好; 对于每个量级,#1s =#0,因此我们可以使用作者逻辑.但是,这在一般情况下如何运作?如果n是某个任意数,则导致n的大多数sig位的序列如下所示:(s)0(s)1(s)0(s)1 ...(k)1(显然序列必须结束1为最大sig位),k可以是[0,s]中的任意数字.那么她的逻辑如何应用?(最值得注意的是,第3步假设#0在通常情况下最多比#1更多1)
谢谢,如果有人能够对此有所了解!谢谢!
我正在从C转向C++ 11并试图找出C++ 11程序(或任何具有内置异常的现代语言)的内存管理范例.具体来说,我在游戏开发方面遇到了麻烦,内存耗尽是一个真正的问题.
在C中,我用来检查malloc的返回值; 并且通常使用自定义分配器.
使用C++,我很困惑; 虽然我喜欢如何构建STL容器,允许自定义分配器.由于STL容器都管理自己的内存,因此只需向向量添加元素即可std::bad_alloc.我该如何防范这些事情?我听说在try/catch块中包装所有抛出的调用都非常昂贵.
但是,允许异常向上移动callstack将允许一堆不能完全执行的函数,并且会导致一些非常棘手的代码.即,如果A->B->C->D是一个callstack,D抛出和A捕获,那么B,C并且D可能由于无法正常完成执行而可能产生一些奇怪的问题.
此外,该nothrow论点似乎允许非常类似C的代码; 虽然我现在看不到普通malloc的好处.
有哪些最佳实践用于编写防异常安全的C++代码以防止内存不足问题?
编辑: 关于progammers.stackexchange的相关答案,主张在控制台中进行无异常的C++设计.不确定这些论点是否仍适用于第8代游戏机
我刚刚从C进入C++
在C(89/90)中,a const实际上不是常量(与#define'd enum,或文字相对),而是一旦设置为只读.即,我可以:
const int x = rand();
Run Code Online (Sandbox Code Playgroud)
这很好 - x直到运行时才知道这一点.因此,我不能
int arr[x]; // error - x is not a compile-time constant
Run Code Online (Sandbox Code Playgroud)
然后,C标准之一(99?)继续进行并允许可变长度数组.虽然我通常使用C语言中的ANSI标准编码,但实际上这已经产生了影响,因为我正在尝试拾取C++ 11.
据我所知,C++不允许使用可变长度数组.但是,许多编译器允许它作为扩展(GCC?).问题是,现在我想学习C++ 11,如果有什么我编码为有效的C我不能告诉++或C++扩展与C99兼容.例如:
std::default_random_engine e{};
std::uniform_int_distribution<int> d{};
const int x{d(e)};
int arr[x]; // compiles
Run Code Online (Sandbox Code Playgroud)
我不知道这是否是有效的C++.显然,x直到运行时才知道值.我想我可能不明白C和C++之间的区别const?
union vec
{
#pragma pack(push,1)
struct
{
float x, y, z;
}
#pragma pack(pop)
float vals[3];
};
Run Code Online (Sandbox Code Playgroud)
考虑上面的定义.(C99匿名工会除外)
我想这个答案可能允许不同的答案取决于编译器的选择,语言的选择和标准的选择.
sizeof(vec) == 3*sizeof(float)&vec.x == &vec.vals[0],等等.v.x然后读取v.vals[0]不管打开,我相信相关的措辞(至少从C99标准来看)是:
与对象的有效类型兼容的类型,
聚合或联合类型,包括其成员中的上述类型之一(包括递归地,子聚合或包含联合的成员),或者
为什么我不能这样做:
class Foo {
void fn();
using fn_t = decltype(fn); //call to non-static member function without an object argument
};
Run Code Online (Sandbox Code Playgroud)
但我能做到
class Foo {
static void fn();
using fn_t = decltype(fn);
};
Run Code Online (Sandbox Code Playgroud)
这篇SO帖子声称:
在未评估的操作数(decltype,sizeof,noexcept,...的操作数)中,您可以在成员函数之外命名非静态数据成员
我对此有点模糊 - 但我认为操作系统需要能够跟踪进程线程正在使用(或保留)虚拟地址空间中的哪些页面.对于程序员通过VirtualAlloc(或您的OS等效)明确请求的内存,这很容易.但是,随着线程执行时堆栈的增长/收缩,堆栈会溢出不同数量的页面.很明显,应用程序员没有请求使用这些页面 - 那么谁来处理对操作系统的请求?C运行时?我不认为操作系统可以自动执行此操作.我缺乏汇编知识来转储可执行文件并检查自己..
我从C(ANSI)跳进C++ 11.这确实是一个奇怪的世界.
我正试图解决以下问题:
int tbl[NUM_ROWS][NUM_COLS] = { 0 };
for (auto row : tbl)
for (auto col : row) // ERROR - can't iterate over col (type int *)
// do stuff
Run Code Online (Sandbox Code Playgroud)
我猜测,这里的理性相当于(在C中)之间的差异:
int v[] = { 1, 2, 3, 4, 5 };
int *u = v;
// (sizeof v) != (sizeof u);
Run Code Online (Sandbox Code Playgroud)
但是,我不太清楚以下是如何工作的:
int tbl[NUM_ROWS][NUM_COLS] = { 0 };
for (auto &row : tbl) // note the reference
for (auto col : row)
// do stuff
Run Code Online (Sandbox Code Playgroud)
逻辑上,我正在考虑auto输入 …