C ++模块(MSVC)中的转发声明 [英] Forward declarations in C++ modules (MSVC)

查看:108
本文介绍了C ++模块(MSVC)中的转发声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在尝试MSVC提供的模块实现,并且遇到了一种有趣的情况。我有两个在其接口中具有相互依赖性的类,这意味着我将不得不使用前向声明来进行编译。以下代码显示了一个示例:

I have been experimenting with modules implementation as provided by the MSVC lately and I've run into an interesting scenario. I have two classes that have a mutual dependency in their interfaces, which means that I'll have to use forward declarations to get it to compile. The following code shows an example:

模块接口

export module FooBar;

export namespace FooBar {
    class Bar;

    class Foo {
    public:
        Bar createBar();
    };

    class Bar {
    public:
        Foo createFoo();
    };
}

模块实现

module FooBar;

namespace FooBar {
    Bar Foo::createBar() {
        return Bar();
    }

    Foo Bar::createFoo() {
        return Foo();
    }
}

现在我想将这两个类分为他们自己的模块,名为 Foo Bar 。但是,每个模块都需要导入其他模块,因为它们的接口相互依赖。并且根据模块提案作为就目前而言,不允许导入圆形接口。 本文建议使用声明的所有权声明,但似乎尚未在模块的MSVC实现中实现。

Now I would like to split these two classes up into their own modules named Foo and Bar. However, each module needs to import the other as their interfaces depend on each other. And according to the modules proposal as it currently stands, circular interface imports are not allowed. This article suggests to use the proclaimed ownership declaration, but it seems that this is not yet implemented in the MSVC implementation of modules.

因此,我认为这是正确的使用MSVC提供的当前实现无法解决当前的情况?还是我缺少其他选择?在这种情况下,情况非常琐碎,但是我在模块化包含许多具有此类依赖关系的类的库时遇到了此问题。我意识到循环依赖关系通常表明设计不好,但是在某些情况下它们是不可避免的或难以重构的。

Therefore, am I correct in assuming that this situation currently cannot be resolved using the current implementation as provided by the MSVC? Or is there some alternative I am missing? In this scenario the situation is pretty trivial, however I encountered this problem while modularizing a library which has many classes that have such dependencies. I realize circular dependencies are often an indication of a bad design, however in certain instances they are unavoidable or difficult to refactor away.

推荐答案

您可以创建第三个模块,该模块仅将前向声明导出到您的每个类(可能有多个类)。

然后您将此模块导入到两个(或所有)模块中,该模块提供

You can create a third module which exports only forward declarations to each of your classes (could be many classes).
Then you import this module into both (or all) of your modules, where it provides the forward declarations needed to implement each module.

不幸的是,MSVC仍然存在模块问题(今天是版本16.7)。尽管这种方法行得通,但您经常会收到完全错误的错误消息;例如,无法将MyClass *转换为MyClass *-不提供转换(此示例发生在您将对同一个类的前期标签直接添加到多个模块中时;编译器将它们视为不同的动物)。

另一个问题是,如果您忘记导入所需的所有模块,则错误消息可能会引起严重误导(该类中没有此类方法),或者编译器因内部错误而中止。

Unfortunately, MSVC has still (today is version 16.7) issues with modules; although this approach works, you get often completely wild error messages; for example, "cannot convert MyClass* to MyClass* - no conversion provided (this example happens when you directly add forward decalarations to the same class into several modules; the compiler considers them different animals).
Another issue is if you forget to import all the modules needed, the error message is either grossly misleading ('no such method in that class'), or the compiler aborts with an internal error.

在他们完成工作之前不要期望太大。

Don't expect too much until they have completed their work.

这篇关于C ++模块(MSVC)中的转发声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆