首页 > 解决方案 > C++ 模板方法中的循环依赖

问题描述

我在 C++ 模板方法中遇到了循环依赖的问题。我意识到这里有几个类似的线程,但它们对我的具体情况没有帮助。这是一个荒谬的例子,但它说明了这个问题:

主文件

#include "A.h"
int main()
{
    float f = 10;
    A a;
    a.foo( f );
}

#pragma once

#include "B.h"
#include <iostream>

class A
{
private:
    B _b;

public:
    A() {}

    std::string getName() const { return "A"; }

    template<typename T> void foo( T t )
    {
        if( _b.getActive() )
            _b.foo( t, this );
        else
            std::cout << "A, " << t << std::endl;
    }
};

溴化氢

#pragma once

#include "A.h"

#include <string>
#include <iostream>

class A;

class B
{
private:
    bool _active;

public:
    B() : _active( false ) {}

    bool getActive() const { return _active; }
    void setActive( bool active ) { _active = active; }

    template<typename T> void foo( T t, const A *a )
    {
        std::cout << "B, " << a->getName() << std::endl;
    }
};

在 Bh 中,我既不能前向声明 A(将得到error C2039: 'getName': is not a member of 'A'),也不能包括 Ah(将得到error C4430: missing type specifier - int assumed.)。

有没有办法解决这个问题,还是我必须完全重构我的代码?

编辑

我正在使用 MSVC 141 (VS 2017) 编译/std:c++latest,顺便说一句。

标签: c++templates

解决方案


我还想添加一个(不太好的)解决方案,但也许它对某些人有帮助:

在调查过程中,我发现我有一个不同的项目使用相同的代码库,它编译时没有任何问题。我注意到不同之处在于新项目将Conformance Mode设置为/permissive-,而旧项目没有。因此,如果您需要 MSVC 的快速解决方案并且不关心标准一致性,您可能需要关闭此选项。这样,上面的代码就像发布的那样工作。

编辑

免责声明:请注意,这可能会破坏代码,正如 Evg 在下面的评论中指出的那样。


推荐阅读