C++ 模块中的前向声明和不完整类型

Forward declarations and incomplete types in C++ modules

我一直在试验 C++20 模块,似乎与通常的 hpp/cpp 方法有些不同。以下代码无法编译(我使用的是 MSVC 的最新预览版)。

foo.ixx

export module foo;

import std.memory;

export
struct Bar;

export
struct Foo {
  std::unique_ptr<Bar> ptr;
};

bar.ixx

export module bar;

import std.core;

import foo;

struct Bar {
  void func(Foo& f) {}
};

main.cpp

import foo;
import bar;

int main() {
  Foo f;
}

我的问题:

  1. 除了将 FooBar 放入一个文件之外,还有更好的解决方法吗?
  2. 这是否意味着模板实例化是在模块“链接”之前完成的?

模块拥有放入其中的声明。如果一个模块拥有一个声明,则所有其他声明也必须是同一模块的一部分。

Bar 被声明为 foo。因此,它的任何其他声明(以及定义 声明)也必须在 foo.

它们不必在同一个文件中,但它们必须在同一个模块中。如果你想让模块foo的用户可以访问Bar的定义,你应该使用模块接口单元分区:

export module foo:BarDef;

import std.core;

export struct Bar {
  void func(Foo& f) {}
};

并且模块的主接口单元必须导入这个分区:

export module foo;

import std.memory;

export struct Bar;

export struct Foo {
  std::unique_ptr<Bar> ptr;
};

export import :BarDef;

MSVC 的模块文件命名约定说 .ixx 应该用于任何接口单元,因此这两个文件都应该是 .ixx 文件。