作者回复: 识货。😇
毕竟这个专栏的篇幅是 30 讲,不是 60 讲或 100 讲啊。
作者回复: 仍然是第3讲里的规则,左值得到左值引用,右值得到右值引用(但要注意右值引用是个左值):
int x = 42;
int& a = x;
int&& b = 42;
auto&& c = a; // int&
auto&& d = b; // int&
auto&& e = std::move(b); // int&&
作者回复: 唉……想办法看看能不能把工具链先升级上去,并测试有没有问题吧。
作者回复: 是说如果一个类Obj既有:
Obj(initializer_list<int>);
又有:
Obj(double);
那你想调用后面那个构造函数,就别用 Obj{1.0} 这种形式,而用 Obj(1.0)。
作者回复: 123456789 有 27 位有效数字(二进制),而 32 位的 float 类型的有效数字数是 24。你说损失了不?
详见
https://zh.wikipedia.org/zh-cn/%E5%96%AE%E7%B2%BE%E5%BA%A6%E6%B5%AE%E9%BB%9E%E6%95%B8
作者回复: 就看你要不要保持值类别了。在应用的代码,一般写 auto 更安全。如果你是写通用的模板代码,那可能就需要写 decltype(auto) 了。但你得仔细考虑一下对象的生命期问题,确保不会返回一个过期的引用。
作者回复: 坚持向前看啊😄
看看工具链有没有升级版本可以支持更新的标准?
作者回复: 哈哈,真是的。谢谢。回头改一下。
作者回复: “龟腚”而已。参考资料 [4a] 里有的:
“用户定义推导指引必须指名一个类模板,且必须在类模板的同一语义作用域(可以是命名空间或外围类)中引入,而且对于成员类模板,必须拥有同样的访问,但推导指引不成为该作用域的成员。”
作者回复: 1. 文稿中不是完整的代码。我拿下面的完整代码测试是没有问题的:
#include <string>
using namespace std;
template <typename T>
struct MyObj {
MyObj(T value)
: value_(value) {}
T value_;
};
MyObj(const char*) -> MyObj<string>;
int main()
{
MyObj obj{"hello"};
}
2. const char* 就是 char const*,没有区别,是同一个东西,都是指向常字符的指针(指针指向的内容不可更改)。如果写成 char* const,那就不一样了——那是指向字符的常指针(指针本身不可更改,指向的内容可更改)。
作者回复: 就是 begin 和 end。对象 c 所属类型所在的名空间里的这两个函数将被优先使用。
作者回复: 内容太多,这两个话题都会讨论到,但可能不会太深。具体参见目录。第 19、20、27 讲。
作者回复: C++,不是 C。这是两种不同的语言。
这个专栏讲的内容是比较确定的,你可以看目录。后面我会讲到函数式和多线程,CAS 可以稍微讲一下。其他内容大概不会覆盖到了……
算法本身很零散,又不算难理解。在我讲到的个别算法之外,其他大家自己看应该不会很复杂。
作者回复: 先升级编译器,解决任何编译问题,再用测试来确保没有问题。
编译期和语言对向后兼容性一直保持得很好的,原则上不应该有问题。不能太保守了。(但也不要激进地每个新版本都升。)
作者回复: Boost 也没什么特别神秘的方法吧。不用 Boost,方法也应该相似的。
我个人一般用 Scott Meyers 教的一个办法:
#define TYPE_DISPLAY(var) \
static type_displayer<decltype(var)> type_display_test
template <typename T> // declaration only for type_displayer;
class type_displayer;
用的时候,就写 TYPE_DISPLAY(变量名字);。
作者回复: 这个已经讲到过了。不会再单独讲。
你上面的变量命名有问题,会让人误以为 it 是个迭代器。它只是元素的引用,并不是迭代器。
作者回复: 多自己试验例子来体会一下。
作者回复: 代码怎么看起来好看怎么用。😂