小编P.W*_*P.W的帖子

迭代器失效规则

C++容器的迭代器失效规则是什么?

优选地以摘要列表格式.

(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)

c++ iterator c++-faq c++11 c++17

509
推荐指数
6
解决办法
11万
查看次数

typedef别名的析构函数

#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)编译的.

c++ destructor typedef language-lawyer

22
推荐指数
2
解决办法
954
查看次数

当simple-capture中的标识符显示为参数的declarator-id时,没有编译器诊断

关于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 在这里

c++ lambda language-lawyer

22
推荐指数
1
解决办法
622
查看次数

这是一个错误吗?Constexpr构造函数默默地变为非constexpr

看看这段代码:

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对象的静态初始化,但它被动态初始化,并且由于"静态初始化命令惨败"而导致问题)

c++ language-lawyer c++17

17
推荐指数
1
解决办法
429
查看次数

在另一个类的构造函数的成员初始值设定项中声明的类是否可以在其外部显示?

考虑以下代码:

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上所有四个编译器的一致性查看.

那么哪个编译器按照标准是正确的?

c++ language-lawyer

17
推荐指数
2
解决办法
824
查看次数

什么是"pch.h",为什么需要将它作为第一个头文件包含在内?

#include "pch.h"
#include <stdio.h>
#include <string.h>
Run Code Online (Sandbox Code Playgroud)

什么是"pch.h"?为什么需要将其作为第一个头文件包含在内?

c c++ visual-studio

16
推荐指数
1
解决办法
7875
查看次数

为什么std :: future和std :: promise不是最终的?

我为为什么类std::futurestd::promise不用final说明符标记感到烦恼。该析构函数不是虚拟的,这样为什么final不加入?基本原理是什么?

c++ language-lawyer c++11 c++14

14
推荐指数
2
解决办法
1541
查看次数

现代C++在多大程度上消除了对设计模式的需求?

1994年推出的GoF设计模式书是用C++语言编写的,许多代码示例都是用C++编写的.其他语言的程序员认为他们的语言不需要这23种设计模式,因为这些语言具有使许多模式冗余的特征.

来自维基百科:

设计模式的一个主要批评是它的模式只是C++缺少功能的变通方法,用冗长的具体模式取代优雅的抽象特征,基本上成为"人类编译器"或"手工生成某些宏的扩展".Peter Norvig演示了设计模式中23种模式中的16种在Lisp或Dylan中被简化或消除(通过直接语言支持).

自Design Patterns Books出版以来,C++经历了五次修订(98,33,11,14,17).那么问题是,现代C++在多大程度上简化或消除了对这23种设计模式的需求?

列出设计模式以及C++语言功能可以消除或简化对该模式的需求.

c++ design-patterns

13
推荐指数
1
解决办法
282
查看次数

P1236R1:为什么c ++标准试图在定义整数时偏离"bit"这个词?

根据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的一部分

c++ language-lawyer c++20

13
推荐指数
1
解决办法
422
查看次数

GCC编译器是否应该为这个涉及[[fallthrough]]属性的不正确的C++代码进行诊断?

我正在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]]; // ill­formed, 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++ gcc gcc-warning fall-through c++17

12
推荐指数
1
解决办法
450
查看次数