Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何向前声明命名空间中的类_C++_Namespaces - Fatal编程技术网

C++ 如何向前声明命名空间中的类

C++ 如何向前声明命名空间中的类,c++,namespaces,C++,Namespaces,我试图在头文件中使用前向声明来减少已使用的#includes,从而减少用户包含我的头文件时的依赖关系 但是,我无法转发使用名称空间的贴花。见下面的例子 a.hpp file: #ifndef __A_HPP__ #define __A_HPP__ namespace ns1 { class a { public: a(const char* const msg); void talk() const; private: const c

我试图在头文件中使用前向声明来减少已使用的#includes,从而减少用户包含我的头文件时的依赖关系

但是,我无法转发使用名称空间的贴花。见下面的例子

a.hpp file:
#ifndef __A_HPP__
#define __A_HPP__

namespace ns1 {

   class a {
   public:
      a(const char* const msg);

      void talk() const;

   private:
      const char* const msg_;
   };
}

#endif //__A_HPP__

a.cpp file:
#include <iostream>

#include "a.hpp"

using namespace ns1;

a::a(const char* const msg) : msg_(msg) {}

void a::talk() const { 
   std::cout << msg_ << std::endl; 
}



consumer.hpp file:
#ifndef __CONSUMER_HPP__
#define __CONSUMER_HPP__

// How can I forward declare a class which uses a namespace
//doing this below results in error C2653: 'ns1' : is not a class or namespace name
// Works with no namespace or if I use using namespace ns1 in header file
// but I am trying to reduce any dependencies in this header file
class ns1::a;

class consumer
{
public:
   consumer(const char* const text) : a_(text) {}
   void chat() const;

private:
   a& a_;
};

#endif // __CONSUMER_HPP__

consumer.cpp implementation file:
#include "consumer.hpp"
#include "a.hpp"

consumer::consumer(const char* const text) : a_(text) {}

void consumer::chat() const {
   a_.talk();
}

test - main.cpp file:
#include "consumer.hpp"

int main() {
   consumer c("My message");
   c.chat();
   return 0;
}
a.hpp文件:
#ifndef\uuuuu水电站__
#定义水电站__
名称空间ns1{
甲级{
公众:
a(常量字符*常量消息);
void talk()常量;
私人:
常量字符*常量消息;
};
}
#endif/\uu A\u水电站__
a、 cpp文件:
#包括
#包括“a.hpp”
使用名称空间ns1;
a::a(constchar*constmsg):msg(msg){}
void a::talk()常量{

std::cout在命名空间
ns1
中向前声明类类型
a

namespace ns1
{
    class a;
}
要在多级名称空间中正向声明类型,请执行以下操作:

namespace ns1
{
  namespace ns2
  {
    //....
     namespace nsN
     {
        class a;
     }
    //....    
  }
}

您正在使用
a
consumer的成员,这意味着它需要具体的类型,您的转发声明在这种情况下不起作用。

要在命名空间
ns1
中转发声明类类型
a

namespace ns1
{
    class a;
}
要在多级名称空间中正向声明类型,请执行以下操作:

namespace ns1
{
  namespace ns2
  {
    //....
     namespace nsN
     {
        class a;
     }
    //....    
  }
}

您使用的是
a
consumer
的成员,这意味着它需要具体的类型,您的转发声明在这种情况下不起作用。

除了从其命名空间中转发声明类(如@billz所说),请记住使用(prepend)当引用前向声明的类或使用子句添加一个
时,该名称空间:

// B.h
namespace Y { class A; } // full declaration of
// class A elsewhere

namespace X {
    using Y::A;   // <------------- [!]
    class B {
        A* a; // Y::A
    };
}
//B.h
命名空间Y{class A;}//的完整声明
//其他A类
名称空间X{

使用Y::A;//从其命名空间内向前声明类(如@billz所说),记住在引用向前声明的类时使用(前置)该命名空间,或者使用
子句添加一个

// B.h
namespace Y { class A; } // full declaration of
// class A elsewhere

namespace X {
    using Y::A;   // <------------- [!]
    class B {
        A* a; // Y::A
    };
}
//B.h
命名空间Y{class A;}//的完整声明
//其他A类
名称空间X{

对于嵌套的名称空间使用Y::A;//,从C++17开始,您可以

namespace ns1::ns2::nsN
{
  class a;
}

对于嵌套名称空间,自C++17以来,您可以

namespace ns1::ns2::nsN
{
  class a;
}

+ 1:我很容易在写C++时生气了,但是我马上知道答案了,只是重新声明了名字空间。我很高兴我记得,我忘记了很多其他东西……托马斯,我刚才试过了,得到了<代码>错误C3083:‘NS1’:“::”的符号必须是一个类型< /代码> @托马斯,我相信只有这样才能工作。命名空间已经存在。@铁不仅必须存在命名空间,而且必须在其中声明类,在这种情况下,在命名空间之外再声明类的点很小。+ 1:自从我愤怒地写C++以来,它很容易10年,但我马上知道了答案,只需重新声明命名空间。我很高兴我记得THA。t、 我忘了太多其他的东西了…@Thomas,我刚刚试过了,得到了
错误C3083:'ns1:':'左边的符号必须是一个类型
@Thomas我相信只有在名称空间已经存在的情况下才有效。@Iron不仅名称空间必须存在,而且类必须在其中声明,在这种情况下,重新定义在命名空间之外初始化。不要为宏使用以两个下划线或下划线和大写字母开头的名称,这些名称是保留的。这不仅仅是命名空间问题。consumer.cpp知道存在类类型a,但不知道具体内容。您尝试调用方法a::talk(),编译器对此一无所知。您仍然需要#包含consumer.cpp中的“a.hpp”,以便编译器知道类的完整接口。此#包含将在.cpp内部,因此不会“分散”通过consumer.hpp。对于宏,不要使用以两个下划线或下划线和大写字母开头的名称,这些名称是保留的。这不仅仅是名称空间问题。consumer.cpp知道有一个类类型a,但不知道具体内容。您尝试调用方法a::talk(),编译器对此一无所知。您仍然需要#包含consumer.cpp中的“a.hpp”,以便编译器知道类的完整接口。此#包含将在.cpp内部,因此不会“分散”通过consumer.hpp.just
class ns1::ns2::nsN::a
怎么样?just
class ns1::ns2::nsN::a
怎么样?