现在很多次,我在 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);
beforeg2
,g2
会突然开始调用错误的东西。这是可维护性的噩梦。
关于c++ - 为什么声明/定义顺序在 C++ 中仍然很重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47376260/