【问题标题】:Can decltype make less recompilationdecltype 可以减少重新编译吗
【发布时间】:2021-07-26 08:02:34
【问题描述】:

我在做一个cpp项目,假设有这么一段代码:

// header1.h
struct Test {
    int a;
    bool func(int b) { return a < b; }
};

// header2.h
#include "header1.h"
void myfunc(int aa) {
    Test t;
    t.a = aa;
    bool res = t.func(3);
    // something else
}

// header3.h
#include "header1.h"
void myfunc(decltype(Test::a) aa) {   // CHANGED HERE
    Test t;
    t.a = aa;
    bool res = t.func(3);
    // something else
}

我总是像headedr2.h 一样编码。但是今天遇到这样一个情况,header1.hTest::a的类型以后可能会变成uint8_tint32_t等。如果它改变了,header2.h 也应该改变。 (我不想进行任何隐式转换。)

也就是说,如果header1.h发生变化,我必须更改header2.h,结果,包括header2.h在内的所有文件都必须重新编译。

现在,我在考虑是否可以像 header3.h 一样使用 decltype 来避免重新编译。换句话说,我在问我是否编码header3.h而不是header2.h,是否可以在更改header1.hTest::a的类型后避免重新编译包含header3.h的文件?

【问题讨论】:

  • 一旦你改变了一个类成员变量的类型,你基本上需要重新编译所有使用这个类的东西。这样的更改通常会更改对象的存储要求(字节大小、对齐方式、填充等)。在您的情况下,如果不重新编译,myfunc 中的 t 变量可能分配了不正确的存储空间。
  • 由于header2.h 包含header1.h,所有包含header2.h 的编译单元都需要在header1.h 更改时重新编译。在header2.h 中使用decltype 的价值在于,如果header1.h 发生更改,您不需要编辑header2.h(并且不要冒忘记进行更改的风险——例如编译失败)。

标签: c++ c++11 compilation decltype


【解决方案1】:

不,如果您更改 header1.h,则必须重新编译包括 header1.h 在内的所有内容。

原因是:编译器如何生成myfunc 的代码而不知道其参数的类型,或者不知道您在myfunc 中使用的Test 类型?

如果您更改struct Test,更改其成员的类型,则使用过时的Test 声明生成的所有代码可能在链接阶段无法编译,或者在运行时可能会出现不可预知的行为.

【讨论】:

    【解决方案2】:

    从编译开始,所有包含"header1"的文件都应该重新编译。

    使用decltype(Test::a) 需要#include,而直接使用int 不需要(定义无论如何都需要它,但可以在cpp 中)。

    使用decltype(Test::a) 可以避免在多个地方更新代码。

    decltype(Test::a) 设置别名可能是有意义的,例如

    struct Test {
        using type_a = int;
        type_a a;
        bool func(type_a b) const { return a < b; }
    };
    

    并使用Test::type_a,这似乎更惯用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      相关资源
      最近更新 更多