使用C++ 11基于范围的正确方法是for
什么?
应该使用什么语法?for (auto elem : container)
,for (auto& elem : container)
或者for (const auto& elem : container)
?还是其他一些?
我曾经认为在C++中,如果构造函数抛出异常,则不会调用此"部分构造"类的析构函数.
但似乎在C++ 11中它不再是真的:我使用g ++编译了以下代码,并将" X destructor
" 打印到控制台.为什么是这样?
#include <exception>
#include <iostream>
#include <stdexcept>
using namespace std;
class X
{
public:
X() : X(10)
{
throw runtime_error("Exception thrown in X::X()");
}
X(int a)
{
cout << "X::X(" << a << ")" << endl;
}
~X()
{
cout << "X destructor" << endl;
}
};
int main()
{
try
{
X x;
}
catch(const exception& e)
{
cerr << "*** ERROR: " << e.what() << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
产量
Standard out: …
Run Code Online (Sandbox Code Playgroud) 这篇文章的评论部分中有一个关于使用std::vector::reserve()
vs.的帖子std::vector::resize()
.
这是原始代码:
void MyClass::my_method()
{
my_member.reserve(n_dim);
for(int k = 0 ; k < n_dim ; k++ )
my_member[k] = k ;
}
Run Code Online (Sandbox Code Playgroud)
我相信要写出元素vector
,正确的做法是打电话std::vector::resize()
,而不是std::vector::reserve()
.
实际上,以下测试代码在VS2010 SP1的调试版本中"崩溃":
#include <vector>
using namespace std;
int main()
{
vector<int> v;
v.reserve(10);
v[5] = 2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我是对的,还是我错了?并且VS2010 SP1是对的,还是错了?
我想比较使用不同分配器分配的STL字符串,例如std::string
使用自定义STL分配器的普通字符串.不幸的是,似乎通常operator==()
在这种情况下不起作用:
// Custom STL allocator to allocate char's for string class
typedef MyAllocator<char> MyCharAllocator;
// Define an instance of this allocator
MyCharAllocator myAlloc;
// An STL string with custom allocator
typedef std::basic_string
<
char,
std::char_traits<char>,
MyCharAllocator
>
CustomAllocString;
std::string s1("Hello");
CustomAllocString s2("Hello", myAlloc);
if (s1 == s2) // <--- ERROR: doesn't compile
...
Run Code Online (Sandbox Code Playgroud)
特别是,MSVC10(VS2010 SP1)发出以下错误消息:
错误C2678:二进制'==':找不到哪个运算符带有'std :: string'类型的左操作数(或者没有可接受的转换)
所以,这样的低级(不太可读)代码:
if (strcmp(s1.c_str(), s2.c_str()) == 0)
...
Run Code Online (Sandbox Code Playgroud)
应该使用.
(在例如存在std::vector
不同分配的字符串的情况下,这也是特别烦人的,其中通常的简单v[i] …
考虑以下代码(以及VirtualAlloc()
返回avoid*
的事实):
BYTE* pbNext = reinterpret_cast<BYTE*>(
VirtualAlloc(NULL, cbAlloc, MEM_COMMIT, PAGE_READWRITE));
Run Code Online (Sandbox Code Playgroud)
为什么reinterpret_cast
选择而不是static_cast
?
我以前认为reinterpret_cast
可以用于例如从整数类型(例如DWORD_PTR
)转换指针,但是从a转换void*
为a BYTE*
,是不是static_cast
可以?
在这种特殊情况下是否存在任何(微妙的?)差异,或者它们是否只是有效的指针转换?
C++标准是否偏爱这种情况,建议采用一种方式而不是另一种方式?
对垃圾收集和基于可达性的泄漏检测的最小支持
(但似乎没有在GCC和Clang中实施.)
为什么标准委员会引入了这种垃圾收集C++ langauge功能?
C++真的需要GC吗?RAII不是一个优秀的模式(可以统一用于内存和非内存资源,如套接字,文件,纹理......)?
GC会破坏使用RAII的C++代码模式的一致性吗?
有人说GC可以派上用场来打破循环依赖,但是weak_ptr
为了这个目的,使用智能指针是不是可以呢?
如果抛出异常会发生什么?如何修改堆栈展开语义以考虑GC?
并且还会IDisposable
引入类似C#的模式吗?
此外,假设在C++中引入了GC,指针语法会不同吗?例如,我们是否会^
像C++/CLI或C++/CX扩展中那样有类似帽子的"指针" ?应该有一种方法可以区分普通的原始指针和"托管"指针,对吧?
要定义整数类型的编译时常量,如下所示(在函数和类范围内),哪种语法最好?
static const int kMagic = 64; // (1)
constexpr int kMagic = 64; // (2)
Run Code Online (Sandbox Code Playgroud)
(1)
也适用于C++ 98/03编译器,而(2)
至少需要C++ 11.这两者之间还有其他差异吗?在现代C++代码中是否应该首选其中一个,为什么?
编辑
我用Godbolt的CE尝试了这个示例代码:
int main()
{
#define USE_STATIC_CONST
#ifdef USE_STATIC_CONST
static const int kOk = 0;
static const int kError = 1;
#else
constexpr int kOk = 0;
constexpr int kError = 1;
#endif
return kOk;
}
Run Code Online (Sandbox Code Playgroud)
对于这种static const
情况,这是GCC 6.2生成的程序集:
main::kOk:
.zero 4
main::kError:
.long 1
main:
push rbp
mov rbp, …
Run Code Online (Sandbox Code Playgroud) 如何从STL容器中删除元素,具有指定值或满足某些条件?
对于不同类型的容器,是否有单一的通用或统一的方法?
我希望存储一个大的d维点矢量(d固定和小:<10).
如果我定义一个Point
as vector<int>
,我认为a vector<Point>
会在每个位置存储指向Point的指针.
但是,如果将a定义Point
为固定大小的对象,如:
std::tuple<int,int,...,int>
或者std::array<int, d>
,程序是否会将所有点存储在连续的内存中,还是会保留额外的间接级别?
如果答案是数组避免额外的间接,那么在扫描时,这会对性能(缓存利用局部性)产生很大影响vector<Point>
吗?
如何wstring
在Windows平台上读取(UTF-8)文件?