c++ - 为什么声明/定义顺序在 C++ 中仍然很重要?

标签 c++ c++11

现在很多次,我在 C++ 中的声明和定义顺序上遇到问题:

struct A {
    void Test() { B(); }
};

void B() {
    A a;
}

当然这可以通过预先声明B()来解决。 通常这足以解决任何这些问题。但是当使用基于模块的仅 header 库或类似复杂的包含系统时,这种声明/定义概念可能真的很痛苦。我在下面包含了一个简单的示例。

现在大多数现代语言编译器对源文件进行两次遍历,以在第一次遍历中构建声明并在第二次遍历中处理定义。将此方案引入 C++ 也不应破坏任何旧代码。因此,

  • 为什么这种方法或类似的方法还没有被引入到 c++ 中?
  • 当前标准中是否有任何相关条款禁止这种方法?

例子

这是一个基于模块的头文件库的示例,由于缺少预声明而导致包含阻塞。要解决这个问题,库的用户必须预先声明“缺失”类,这是不可行的。 当然,这个问题可能会通过使用在定义之前对所有声明进行排序的公共(public)包含 header 来解决,但是通过两次传递,此代码也可以工作,无需修改。

oom.h

#pragma once
#include "string.h"

struct OOM {
    String message;
};

string.h

#pragma once
#include "array.h"

struct String {
    Array data;
};

array.h

#pragma once

struct Array {
    void Alloc();
};

#include "oom.h"

void Array::Alloc() { throw OOM(); }

str_usage.cpp

#include "string.h"
int main() {
    String str;
}

最佳答案

void f(int);
void g() { f(3.14); }
void f(double); 

g 当前调用 f(int),因为它是唯一可见的 f。在你的世界里它叫什么?

  • 如果它调用 f(double),您就破坏了大量现有代码。
  • 如果你想出一些规则让它仍然调用f(int),那么这意味着如果我写

    void g2() { f2(3.14); }
    void f2(double);
    

    然后为参数引入一个更差匹配 - 例如,void f2(int); before g2, g2 会突然开始调用错误的东西。这是可维护性的噩梦。

关于c++ - 为什么声明/定义顺序在 C++ 中仍然很重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47376260/

相关文章:

c++ - 新初始化程序中的 decltype(auto)?

c++ - x * 0.1 和 x/10 之间的区别?

c++ - 一个对象什么时候可以有一个但不是两个非零大小,一个或多个字节的存储空间?

c++ - 将 QString 日期(RFC 822 格式)转换为另一种基于文化的 QString 格式

c++ - 使用 lambda 作为参数:std::function 还是模板?

c++ - 当在类主体中使用 unique_ptr 声明析构函数作为同一类的成员时出现编译器错误

C++11 多播委托(delegate)实现

c++ - 如何在 GitHub 存储库的团队服务构建中链接第三方库 (.lib)?

c++ - 使用带有 cmake 的 OpenGL ES 2.0 生成 iOS 静态库

c++ - 静态链接 C++ OpenCV