C++容器的迭代器失效规则是什么?
优选地以摘要列表格式.
(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)
#include <iostream>
struct A { ~A(); };
A::~A() {
std::cout << "Destructor was called!" << std::endl;
}
typedef A AB;
int main() {
AB x;
x.AB::~AB(); // Why does this work?
x.AB::~A();
}
Run Code Online (Sandbox Code Playgroud)
上述程序的输出是:
Destructor was called!
Destructor was called!
Destructor was called!
Run Code Online (Sandbox Code Playgroud)
我假设前两行属于用户析构函数调用,而第三行是由于在退出main
函数范围时调用析构函数.
根据我的理解,typedef是类型的别名.在这种情况下AB
是别名A
.
为什么这也适用于析构函数的名称?非常感谢对语言规范的引用.
编辑:这是在macOS High Sierra版本10.13.3上使用Apple LLVM版本9.1.0(clang-902.0.39.1)编译的.
关于lambda捕获的部分([expr.prim.lambda.capture]/5)表明了这一点
如果simple-capture中的标识符显示为lambda-declarator的parameter-declaration-clause参数的declarator-id,则该程序格式错误.
考虑以下示例:
#include <iostream>
int main ()
{
auto foo = 1234;
auto bar = [foo](int foo) { std::cout << foo << '\n'; };
bar(4321);
}
Run Code Online (Sandbox Code Playgroud)
最新的GCC版本(8.2.0 - 2018年7月26日发布)没有对此进行诊断.最新的Clang版本(7.0.0 - 2018年9月19日发布)也没有.
是否应该从这些编译器(如参考文献中提到)进行诊断(错误/警告),方法如下:
// parameter and simple-capture have the same name
Run Code Online (Sandbox Code Playgroud)
Godbolt Demo 在这里
看看这段代码:
struct NonConstexpr {
NonConstexpr() { }
};
template <typename T>
struct Bar {
NonConstexpr nonConstexpr;
constexpr Bar() { }
};
struct Foo {
Bar<void> bar;
constexpr Foo() { }
};
Run Code Online (Sandbox Code Playgroud)
Foo
有一个成员,Foo::bar::nonConstexpr
有一个非constexpr构造函数.所以,我的期望是这不应该编译.但它与gcc,clang和msvc编译.这是编译器错误,还是某些规则允许编译此代码?
如果我直接添加NonConstexpr
成员Foo
,代码将不再编译.
(我遇到了这个问题,因为我期望全局Foo
对象的静态初始化,但它被动态初始化,并且由于"静态初始化命令惨败"而导致问题)
考虑以下代码:
struct Foo {
void* p;
Foo() : p{(class Bar*)0} {}
};
Bar* bar;
Run Code Online (Sandbox Code Playgroud)
最新版本的GCC(8.2)和Clang(7.0.0)无法编译它.ICC也是如此(19.0.1).
但是MSVC(v19.16)干净利落地编译它.
GCC的错误是: error: 'Bar' does not name a type; did you mean 'char'?
Clang和ICC发出类似的消息.
godbolt上所有四个编译器的一致性查看器.
那么哪个编译器按照标准是正确的?
#include "pch.h"
#include <stdio.h>
#include <string.h>
Run Code Online (Sandbox Code Playgroud)
什么是"pch.h"?为什么需要将其作为第一个头文件包含在内?
我为为什么类std::future
而std::promise
不用final
说明符标记感到烦恼。该析构函数是不是虚拟的,这样为什么final
不加入?基本原理是什么?
1994年推出的GoF设计模式书是用C++语言编写的,许多代码示例都是用C++编写的.其他语言的程序员认为他们的语言不需要这23种设计模式,因为这些语言具有使许多模式冗余的特征.
来自维基百科:
设计模式的一个主要批评是它的模式只是C++缺少功能的变通方法,用冗长的具体模式取代优雅的抽象特征,基本上成为"人类编译器"或"手工生成某些宏的扩展".Peter Norvig演示了设计模式中23种模式中的16种在Lisp或Dylan中被简化或消除(通过直接语言支持).
自Design Patterns Books出版以来,C++经历了五次修订(98,33,11,14,17).那么问题是,现代C++在多大程度上简化或消除了对这23种设计模式的需求?
列出设计模式以及C++语言功能可以消除或简化对该模式的需求.
根据P1236R1,现在整数类型用数字定义,不再用位.
type minimum range exponent N
signed char 8
short 16
int 16
long 32
long long 64
Run Code Online (Sandbox Code Playgroud)
而不是定义标准仍然缺乏的"位"的含义,C++选择不这样做,而是在术语中定义那些类型range exponent
.
为什么?
为什么不依靠"bit"这个词更好?
这个提案中有哪些"不可观察的位"?
P1236R1是C++ 20的一部分
我正在GCC编译器版本7.1.0上测试C++ 17的功能.这与fallthrough
属性有关,以下示例(实例)在此处改编自在线CPP参考
#include "iostream"
using namespace std;
int f(int n) {
switch (n) {
case 1:
case 2:
n = n + 20;
[[fallthrough]];
case 3: // no warning on fallthrough
n = n + 30;
case 4: // compiler may warn on fallthrough
[[fallthrough]]; // illformed, not before a case label
//n = n + 40; //commented out to test if compiler will warn.
}
return n;
}
int main()
{
cout << …
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++17 ×3
c++11 ×2
c ×1
c++-faq ×1
c++14 ×1
c++20 ×1
destructor ×1
fall-through ×1
gcc ×1
gcc-warning ×1
iterator ×1
lambda ×1
typedef ×1