实现或定义在未命名/匿名命名空间内声明的类或函数

时间:2011-07-23 00:08:49

标签: c++ namespaces implementation

在内部定义的未命名(匿名)命名空间之外定义函数或类成员的实现是否合法。 我的编译器接受它但我想确定它是合法的 e.g。

////////////////
// foo.cpp 

namespace {
 struct X
 {
 void foo(int x);
 };
}

// Is this legal?
void X::foo(int x)
{
}

原因是我想避免因我们的解密格式而施加的不必要的缩进

4 个答案:

答案 0 :(得分:4)

这与以下内容没有什么不同,这完全是合法的:

namespace ns {
    struct s {
        void f();
    };
}

using namespace ns;

void s::f() { }

命名命名空间中的名称被带入全局命名空间,因此可以为它们提供定义。与未命名的命名空间的唯一区别是它没有名称(实际上,它有一些唯一的,不可知的名称),using namespace是隐式的。

答案 1 :(得分:0)

#include <iostream>
using namespace std;

namespace
{
  struct X
  {
     X(int);
     int x_;
  };
}

X::X(int x) : x_(x) {}

int main()
{
   X x(5);

   cout << x.x_ << "\n";
   return 0;
}

在gcc 4.6.0下编译(并运行)

答案 2 :(得分:0)

是。这完全合法。 未命名命名空间的区别在于,命名空间的内容仅在其声明的文件中可用。如果它在.h文件中,则会将其添加到所有后续.cpp文件中,并且每个.cpp文件都将具有namespace内容的唯一副本。 / p>

实际上,这是一种声明全局static变量的更好方法。现在看,它会产生什么样的差异:

namespace {
 struct X
 {
   void foo(int x);
 };
 int i;  // declare this global variable
}

如果您将此代码放在头文件中,那么无论该头文件是#include,所有这些.cpp文件都会在其中包含int i;的不同副本。在一个i文件中更改.cpp的值不会影响其他.cpp文件。

此外,它不会为多个定义提供链接器错误,因为它在未命名的namespace中。

编辑:要对其进行更多评估,请按以下方式定义命名空间:

// x.h
namespace
{
  struct X
  {
    void foo(int x)
    {
      static int c;  // static inside the function
      cout<<"a = "<<(c++)<<endl;
    }
  };
}

现在#include此标头文件包含2个不同的.cpp个文件。在他们两个中尝试使用foo()的对象调用X。它会打印出来:

a = 0
a = 0

这意味着 X::foo() 文件中的.cpp 不同。如果您给namespace一个名字并重复同样的事情,它将输出

a = 0
a = 1

因此,未命名的namespace会为每个翻译单元创建不同的副本。

答案 3 :(得分:0)

在您的方案中它是合法的,但在一种情况下,它会导致编译器模糊错误。

如果在X.h中有另一个类:

// X.h
struct X
{
    void foo(int x) { }
};

在foo.cpp中,需要使用X.h中定义的X

////////////////
// foo.cpp 
#include "X.h"

namespace {
    struct X
    {
        void foo(int x);
    };

    // use the X declared in anonymous namespace
    void test()
    {
        X x;
        x.foo(3);
    }
}

// reference to 'X' is ambiguous
void X::foo(int x)
{
}

void otherFunction()
{
    // Use struct X in X.h
    ::X x;
    x.foo(3);
}

如果将实现代码留在匿名命名空间之外,编译器会抱怨含糊不清。如果将实现代码移到匿名命名空间中,它可以正常工作。