如果使用嵌套命名空间,如何转发声明 C++ 结构?

How to forward declare a C++ struct in case nested namespaces are used?

我有以下 C++ 代码

A.h

namespace x {
namespace y {
namespace z {
   
struct Container;

class A
{
public:
    A(Container& _container);
    
    void info();
    
private:
    Container& container;
};

}
}
}

A.cpp

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

namespace x {
namespace y {
namespace z {

A::A(Container& _container) : container(_container) {}

void A::info() {
    std::cout << "Instance of A!" << std::endl;
}

}
}
}

Container.h

#include "A.h"

namespace x {
namespace y {
namespace z {

struct Container {

    Container(): a(*this) {}
    A a;
};

}
}
}

main.cpp

#include <cstdlib>
#include "Container.h"

int main(int argc, char** argv) {
    
    x::y::z::Container container;
    
    container.a.info();

    return 0;
}

上面提到的代码是可以编译和工作的。

但是假设我将 Container.hz namespace 中移出并放入 y namespace(嵌套在 x namespace)。所以代码看起来像那样

A.h

namespace x {
namespace y {
namespace z {
   
struct Container;

class A
{
public:
    A(x::y::Container& _container);
    
    void info();
    
private:
    x::y::Container& container;
};

}
}
}

A.cpp

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

namespace x {
namespace y {
namespace z {

A::A(x::y::Container& _container) : container(_container) {}

void A::info() {
    std::cout << "Instance of A!" << std::endl;
}

}
}
}

Container.h

#include "A.h"

namespace x {
namespace y {

struct Container {

    Container(): a(*this) {}
    x::y::z::A a;
};

}
}

main.cpp

#include <cstdlib>
#include "Container.h"

int main(int argc, char** argv) {
    
    x::y::Container container;
    
    container.a.info();

    return 0;
}

在这种情况下,编译会失败并显示以下错误消息:

In file included from A.cpp:7:
A.h:26:22: error: expected ')' before '&' token
   26 |     A(x::y::Container& _container);
      |      ~               ^
      |                      )
A.h:31:11: error: 'Container' in namespace 'x::y' does not name a type
   31 |     x::y::Container& container;
      |           ^~~~~~~~~
A.cpp:14:5: error: expected constructor, destructor, or type conversion before '(' token
   14 | A::A(x::y::Container& _container) : container(_container)
      |     ^

如果我将 Container.hz namespace 移到 y [=21] 中,谁能告诉我为什么会弹出这些错误消息=] 嵌套在 x namespace?

问题是您从未在 A.h 中声明 x::y::Container。您确实声明了 x::y::z::Container,但没有命名相同的类型。只需将声明移至 y 命名空间:

namespace y {
namespace z {
   
struct Container;

进入->

namespace y {

struct Container;

namespace z {