导出命名空间之后的所有内容都没有导出吗?

Posted

技术标签:

【中文标题】导出命名空间之后的所有内容都没有导出吗?【英文标题】:Is everything after an exporting namespace not exported? 【发布时间】:2018-03-10 05:50:05 【问题描述】:

我正在阅读有关模块的内容,我希望做这样的事情:

a.cpp

module foo.a;

export namespace foo 
    struct A 
        void doA();
    ;


import foo.b;
void foo::A::doA() 
     B.doB();

b.cpp

module foo.b;

export namespace foo 
    struct B 
        void doB();
        void start();
    ;


import foo.a;
import std.io;
void foo::B::doB() 
     std::cout << "Stuff done!" << std::endl;


void foo::B::start() 
     A.doA();

main.cpp

import foo.b;

int main() 
    foo::B.start();

由于模块接口不能相互使用,为了使其工作,导出的命名空间之后的所有内容都不能是接口的一部分。根据当前的TS,以上是否正确?对于实现中的循环依赖,是否需要拆分成另一个文件?

【问题讨论】:

您将代码错误地标记为 c/c++。请将其标记为 Typescript。 @StarShine - 你在做什么? @StarShine - 那我建议你更新你的知识。 @StoryTeller 好的,很抱歉,因为这对我来说是新的。从en.cppreference.com/w/cpp/experimental 我了解到这仍然是实验和草稿阶段。 Cppreference.org 列出了关键字,但链接后面还没有内容。 @StarShine - 有 CppCon 会谈。 Here's the one from 2015。这更具介绍性,但可能与提案的当前状态不同。他们最初的目标是将其添加到 C++17 中。 【参考方案1】:

来自Working Draft, Extensions to C++ for Modules(参见Experimental C++ Features),第13 页,§10.7.2:3:

模块M1 对模块M2 具有接口依赖关系,如果该模块 M1 的接口包含一个指定 M2 的模块导入声明。一种 模块本身不应具有传递接口依赖关系。

例子:

// Interface unit of M1
export module M1;
import M2;
export struct A  ;

// Interface unit of M2
export module M2;
import M3;

// Interface unit of M3
export module M3;
import M1; // error: cyclic interface dependency M3 -> M1 -> M2 -> M3

Q:“实现中的循环依赖,是否需要拆分成另一个文件?”

答:是的。


Q:“根据目前的TS,以上是否正确?”

答:没有。

在你的代码中,你有一个错误,因为foo.afoo.b 形成了一个循环接口依赖

【讨论】:

所以界面是整个文件,而不仅仅是导出的东西。有趣的。我猜这是因为必须编译整个接口单元才能生成接口二进制文件。 @GuillaumeRacicot:不,interface 只是导出的项目([dcl.module.interface]/1)。但是,受限制的是接口unit @DavisHerring 啊是的,这就是我的意思。我仍然不习惯所有这些新术语!【参考方案2】:

是的,您必须为至少一个模块(概念上“低级”的模块)使用单独的实现文件。 PDTS 的 [dcl.module.import]/3 说

如果M1 的模块接口包含一个提名@987654325 的module-import-declaration,则一个模块M1 有一个接口依赖 @。一个模块不应该对自己有一个传递接口依赖。

无论module-import-declaration 的位置如何,这都适用,因为export 可以在模块接口单元中的任何位置多次出现。该规则旨在防止两个模块中的每一个模块的类型和模板出现在另一个模块的接口中,因为这样就不能“首先”导入任何一个。

【讨论】:

您愿意引用PDTS的相关信息吗?这将使答案更完整。 @GuillaumeRacicot:好的,完成;并不是说 gsamaras 没有先做。 没关系。您实际上添加了其他答案中缺少的一些信息。它使事情更加清晰。我没想过重新开放出口。谢谢!

以上是关于导出命名空间之后的所有内容都没有导出吗?的主要内容,如果未能解决你的问题,请参考以下文章

React + antd TS2694:命名空间'React'没有导出成员

命名空间“Electron.CrossProcessExports”没有导出成员“远程”

命名空间“NodeJS”没有导出成员“Require”

TS2694 (TS) 命名空间 'angular' 没有导出的成员 'ui'

TypeScript躬行记——命名空间

Javascript命名空间 - 如何根据命名导出函数范围内定义的函数和变量?