作者回复: 用默认构造函数代表空,或者用 optional<对象> (不构造)代表空,或者抛异常代表不正常(视是否不正常而定)。
optional 会在第 22 讲里讨论。
作者回复: 简单来说,在对本地变量进行返回时,不用 std::move。实际上,我在第 3 讲就写了:
“有一种常见的 C++ 编程错误,是在函数里返回一个本地对象的引用。由于在函数结束时本地对象即被销毁,返回一个指向本地对象的引用属于未定义行为。理论上来说,程序出任何奇怪的行为都是正常的。
“在 C++11 之前,返回一个本地对象意味着这个对象会被拷贝,除非编译器发现可以做返回值优化(named return value optimization,或 NRVO),能把对象直接构造到调用者的栈上。从 C++11 开始,返回值优化仍可以发生,但在没有返回值优化的情况下,编译器将试图把本地对象移动出去,而不是拷贝出去。这一行为不需要程序员手工用 `std::move` 进行干预——使用`std::move` 对于移动行为没有帮助,反而会影响返回值优化。”
作者回复: 多谢。已修正。
作者回复: 看这个页面吧:
https://en.cppreference.com/w/cpp/compiler_support
目前 GCC 领先一些(可以用 -std=c++2a 启用 20 的功能),但还没有哪家完整支持 C++20。
作者回复: 对于功能和版本的关系,这个页面比较全:
https://en.cppreference.com/w/cpp/compiler_support
作者回复: C++编译器哪会做这么不必要的事……就是一次移动。如果有返回值优化的话,一次移动都不会有。
作者回复: 对,是调用移动构造变成调用拷贝构造,如果原来就直接返回值优化掉了,那不会变化。
作者回复: VS 2017 下也能过的。你没有按环境要求里说的加上 /std:c++17。了解细节,可以看参考资料 [3]。