• jerry.tan
    2019-12-30
    您好老师, 请问想学C++ 您有什么比较好的推荐的开发工具吗 谢谢

    作者回复: 第 21 讲会讨论一点工具。不过你指的是什么工具呢?……如果你用 Windows,就从 Visual Studio 的免费 Community 版开始吧。

     4
     2
  • 李亮亮
    2019-12-30
    我觉得我学习这个专栏只是为了能看懂这些新特性,写是写不出来,规则太多太复杂了。

    作者回复: 很少需要自己写的。就像学了微积分大部分人也没机会用一样😂。但一点都看不懂也是会很有问题的。

    
     1
  • 陈志恒
    2020-02-04
    老师好,有个小疑问,文中提到:

    “上一讲的结尾,我们给出了一个在类型参数 C 没有 reserve 成员函数时不能编译的代码:”


    这里提到使用 if constexpr,可以解决上述问题。这里没有过多的解释,我理解是:使用if constexpr之后,如果没有reserve成员,那就会在编译期跳过这个if中的内容,因此不会检查container.reserve()。

    不知道理解是否正确?
    展开

    作者回复: 对。一般的 if 是运行期条件语句;if constexpr 是编译期条件语句。

    
    
  • 光城~兴
    2020-01-08
    对老师的输出函数进行修改:如下

    template<typename T, typename Cont>
    auto output_element(std::ostream &os, const T &element,
                        const Cont &)
    -> typename std::enable_if<is_pair<typename Cont::value_type>::value, bool>::type {
        os << element.first << " => " << element.second;
        return true;
    }

    template<typename T, typename Cont>
    auto output_element(std::ostream &os, const T &element,
                        const Cont &)
    -> typename std::enable_if<!is_pair<typename Cont::value_type>::value, bool>::type {
        os << element;
        return false;
    }

    调用处:
    output_element(os, elem, container);

    这个方法学习自老师之前讲过的SFINAE!

    另外,针对老师的代码有些疑问:
    老师代码调用处:
    output_element(os, *it, container, is_pair<element_type>());
    实际上在这里就确定了element_type是不是pair,也就是这里传递进去直接就是true_type或者false_type,针对,map/vector/set等直接就可以区分开来,不需要写:std::declval<typename Cont::key_type>()。
    也是可以正常完成输出的,但是当传递的是true_type且容器没有key_type的时候就是SFINAE问题,调用另一个重载函数。
    问题是,一个容器元素是pair,那么is_pair<element_type>()就是true_type,而既然是pair了,也就有了key_type,所以这个必然成立,也就是写与不写都可以。另外,当不是pair,就是false_type,肯定调false_type的output_element重载咯,所以我得出这里写这个std::declval<typename Cont::key_type>()没有啥子用,并且代码测试过确实可以不写,望老师指点!
    展开

    作者回复: 我并不希望把vector<pair<…>> 输出成“=>”的形式。我要仅在输出map、unordered_map的元素时才使用“=>”。

     2
    
  • 光城~兴
    2020-01-07
    constexpr变量仍是const这一块的例子:
    ```cpp
    constexpr int a = 42;
    constexpr const int& b = a;
    ```
    第二行会报错 需要一个常量表达式
    去掉constexpr是不是更好? 貌似对这一块解释没影响~
    展开

    作者回复: 关键是你怎么用 b。如果你需要它是编译期常量,它就应该是 constexpr。

    
    
  • 花晨少年
    2020-01-04
    为什么文章开头提到的两个例子,都是合法的吗,编译运行都没问题。
    第一个例子理所当然的像应该有问题,但是仔细想了下,为什么要有问题呢,数据大小为什么就要编译器确定呢,运行期确定不行吗。而结果是确实没有问题,这里面的玄机是什么呢
    第二个例子应该是 int a[n];吧
    第二个例子是因为const常量的原因,编译器会强制sqr函数编译器运行特定参数吗

    作者回复: 对,纠正得对。我回头改一下。

    能不能编译本身不是关键。关键是答案不明显,依赖于一些细微的 C++ 规则。

    
    
  • tt
    2019-12-30
    文中一开始用constexpr
    改造的例子,之所以可以,一定是在使用constexpr的地方“就地”调用了赋值运算符右侧的函数,这样才能得到一个编译期的常量,所以,“内联”是constexpr的应有之意。但是在类外,必须加上inline才可以。

    const本质是一个运行时常量,constexpr才是编译期常数,除了内联展开这个含义,再根据文中ODR的表述,说明constexpr变量是切实分配了内存空间的,是一个左值对象。综合上面的考虑,constexpr意味着被声明的对象是存放在数据段里面的。


    constexpr 变量模板表达一个和某个类型相关的编译期常量,让变量也可以是模板,这句话在本课中,我觉得理解成“把模板对象用一个变量命名”更合适,即把所有符号都绑定到了一个实体上,这样if constexpr才变得可行。解决了上一讲中说的c++中不能像Python一样写代码的问题。
    展开

    作者回复: 作为编译期常数,没理由认为一个 constexpr 变量一定会在数据段里的,尤其是优化编译的情况。一般而言,只有非优化编译、又有 ODR-use 才能在 data 段里找到其定义。

    
    
  • hello world
    2019-12-30
    如果没有consrexpr条件语句那输出函数就应该写两个吧,也是用sfinae,用那种enable_if形式,true or false

    作者回复: 是,然后要么会有重复的代码,要么得再封装函数来复用。

    
    
我们在线,来聊聊吧