A(3)在"Here"打印之前,不应该暂时销毁吗?
#include <iostream>
struct A
{
int a;
A() { std::cout << "A()" << std::endl; }
A(int a) : a(a) { std::cout << "A(" << a << ")" << std::endl; }
~A() { std::cout << "~A() " << a << '\n'; }
};
int main()
{
A a[2] = { A(1), A(2) }, A(3);
std::cout << "Here" << '\n';
}
Run Code Online (Sandbox Code Playgroud)
输出:
A(1)
A(2)
A(3)
Here
~A() 3
~A() 2
~A() 1
Run Code Online (Sandbox Code Playgroud)
我正在阅读 B. Stroustrup 的《C++ 编程语言》,其第 11.4.3.4 节“可变 Lambdas”,其中内容如下:
通常,我们不想修改函数对象(闭包)的状态,所以默认情况下我们不能。也就是说,
operator()()生成的函数对象(第 11.4.1 节)是一个const成员函数。万一我们想要修改状态(而不是修改通过引用捕获的某些变量的状态;第 11.4.3 节),我们可以声明 lambda mutable。
我不明白为什么默认值operator()()是const通过值捕获变量时的。这样做的理由是什么?当我更改复制到函数对象中的变量的值时,可能会出现什么问题?
我可以理解编译器正在下面的代码中执行copy-elision,因为复制和移动构造函数不会在所谓的copy-initializationdone in中调用main().查看实例.
#include <iostream>
struct S {
S() = default;
S(const S&) { std::cout << "copy ctor" << '\n'; }
S(S&&) { std::cout << "move ctor" << '\n'; }
};
int main() {
S s = S();
}
Run Code Online (Sandbox Code Playgroud)
但是当我删除移动构造函数时,我无法理解为什么代码不能编译,如下所示:
#include <iostream>
struct S {
S() = default;
S(const S&) { std::cout << "copy ctor" << '\n'; }
S(S&&) = delete;
};
int main() {
S s = S();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我在§12.8/ 32(N4140)中找不到任何可能禁止使用或省略复制构造函数的内容 …
我正在尝试?使用类型打印中文字符wchar_t,char16_t并且char32_t没有成功(实例)
#include <iostream>
int main()
{
char x[] = "?"; // Chinese character with unicode point U+4E2D
char y[] = u8"?";
wchar_t z = L'?';
char16_t b = u'\u4e2d';
char32_t a = U'\U00004e2d';
std::cout << x << '\n'; // Ok
std::cout << y << '\n'; // Ok
std::wcout << z << '\n'; // ??
std::cout << a << '\n'; // prints the decimal number (20013) corresponding to the unicode point …Run Code Online (Sandbox Code Playgroud) B.Stroustrup在他的新书(TCPL第4版)第6.2.8节中说明如下:
C++的基本类型的某些方面(例如int的大小)是实现定义的(第6.1节).
稍后,在第150页中,我们有以下示例:
int_least16_t y; // at least 2 bytes (just like int)
int_least32_t yy // at least 4 bytes (just like long)
Run Code Online (Sandbox Code Playgroud)
我对这两个注释的解释是int(或a long)的大小是实现定义的,但它们的最小大小总是分别等于2和4个字节.也就是说,sizeof(int) >= 2而且sizeof(long) >= 4,对任何一种方法.
首先,这是正确的吗?如果是这样,标准中的内容在哪里?
众所周知,下面的片段打印Derived或类似的东西.
#include<iostream>
#include<typeinfo>
class Base { public: virtual ~Base(){} };
class Derived : public Base{};
int main()
{
Derived d;
Base& b = d;
std::cout << typeid(b).name() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
但我想从标准(N4140)的第5.2.8/2段中了解如何得出结论.例如,b肯定是一个glvalue,但类型Base&不一样Base,所以我不能说那b是多态的.我错过了什么?
B. Stroustrup在他的书"TCPL"第4版的第265页上有以下例子:
struct Point{
int x, y, z;
constexpr Point up(int d) { return {x, y, z+d}; }
constexpr Poind move(int dx, int dy) { return {x+dx, y+dy}; }
};
Run Code Online (Sandbox Code Playgroud)
后来他在第266页显示:
constexpr Point p1 {10, 20, 30}; // the default constructor is constexpr
Run Code Online (Sandbox Code Playgroud)
从N4140的§7.1.5/ 4开始,我发现了以下相关要点:
- (4.4)其函数体应为
= default,或其函数体的复合语句应满足constexpr函数的函数体的约束;- (4.5)应初始化每个非变量非静态数据成员和基类子对象(12.6.2);
关于上面的要点,我有两点意见:
struct Point具有函数体是否正确= default?yes,我也在争论编译器为struct Pointis 生成默认构造函数的事实,constexpr因为这个构造函数没有初始化成员x,y并且z与上面的项目符号(4.5)相矛盾.我在这里纠正吗?编辑我正在介绍第三个问题,我认为总结了我在这个问题上遇到的主要困难.
我无法生成constexpr其body等于的默认构造函数的示例= default …
下面的代码段似乎没问题,我相信声明A a(std::move(b).toA());会main()调用隐式声明的类的移动构造函数A,因为A它没有用户定义的复制构造函数,它没有用户定义的复制赋值运算符,它没有用户定义的移动赋值运算符,也没有用户定义的析构函数(参见§12.8/ 9 N4140).但是,当我取消注释下面的移动构造函数时A(A&&) { std::cout << "move A" << '\n'; },我收到了Illegal instruction消息.查看实例.为什么是这样?
#include <iostream>
#include <memory>
class A {
public:
// A(const A&) { std::cout << "copy A" << '\n'; }
// A(A&&) { std::cout << "move A" << '\n'; }
A(std::unique_ptr<int>&& u_ptr) : u_ptr(std::move(u_ptr)) {}
const int& getInt() { return *u_ptr; }
private:
std::unique_ptr<int> u_ptr;
};
class B {
public:
B(int u_ptr) : u_ptr(new …Run Code Online (Sandbox Code Playgroud) c++ ×8
c++14 ×3
c++11 ×1
constexpr ×1
construction ×1
copy-elision ×1
cout ×1
destruction ×1
lambda ×1
polymorphism ×1
temporary ×1