简体   繁体   English

实现或定义在未命名/匿名命名空间内声明的 class 或 function

[英]implementing or defining class or function declared inside an unnamed/anonymous namespace

Is it legal to define the implementation of a function or class members outside the unnamed (anonymous) namespace they've been defined inside.在内部定义的未命名(匿名)命名空间之外定义 function 或 class 成员的实现是否合法。 My compiler accepts it but I want to be sure it's legal eg我的编译器接受它,但我想确保它是合法的,例如

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

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

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

The reason is I would like to avoid the unnecessary indentation imposed by our uncrustify formatting原因是我想避免我们的 unrustify 格式带来的不必要的缩进

It is really no different than the following, which is totally legit:它实际上与以下内容没有什么不同,这是完全合法的:

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

using namespace ns;

void s::f() { }

The names from the named namespace are brought into the global namespace and thus definitions can be provided for them there.命名命名空间中的名称被带入全局命名空间,因此可以在那里为它们提供定义。 The only difference with the unnamed namespace is that it has no name (really, it has some unique, unutterable name) and the using namespace is implicit.与未命名命名空间的唯一区别是它没有名称(实际上,它有一些唯一的、无法说出的名称)并且using namespace是隐式的。

It's legal in your scenario, but in one scenario, it will cause compiler ambiguous error.这在您的场景中是合法的,但在一种情况下,它会导致编译器模棱两可的错误。

In case have another class in Xh:如果 Xh 中有另一个 class:

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

And in foo.cpp, need to use the X defined in Xh而在foo.cpp中,需要用到Xh中定义的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);
}

if leave the implementation code out of the anonymous namespace, compiler complains ambiguous.如果将实现代码留在匿名命名空间之外,编译器会抱怨模棱两可。 If move the implementation code inside anonymous namespace, it works fine.如果将实现代码移动到匿名命名空间内,它可以正常工作。

#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;
}

Compiles (and runs) under gcc 4.6.0在 gcc 4.6.0 下编译(并运行)

Yes.是的。 It's perfectly legal.这是完全合法的。 The difference an unnamed namespace makes is that, the content of the namespace is available only within the file it's declared.未命名命名空间的不同之处在于,命名空间的内容仅在其声明的文件中可用。 If it's in .h file then, it will be added to all the subsequent .cpp file and every .cpp file will have a unique copy of the contents of the namespace .如果它在.h文件中,那么它将被添加到所有后续的.cpp文件中,并且每个.cpp文件都将具有namespace内容的唯一副本。

In fact it's a better way to declare a global static variable.实际上,这是声明全局static变量的更好方法。 Now see, what kind of difference it will make:现在看看,它会产生什么样的不同:

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

If you put this code inside a header file then, wherever that header file is #include ed, all those .cpp file will have a different copy of int i;如果将此代码放在 header 文件中,那么无论 header 文件是#include ed,所有这些.cpp文件都将具有不同的int i; inside them.在他们里面。 Changing the value of i in one .cpp file doesn't affect the other .cpp file.在一个.cpp文件中更改i的值不会影响另一个.cpp文件。

Moreover, it will not give linker error for multiple definitions, since it's in unnamed namespace .此外,它不会对多个定义给出 linker 错误,因为它位于 unnamed namespace中。

Edit : To evaluate it more, define the namespace as following:编辑:要对其进行更多评估,请按如下方式定义命名空间:

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

Now #include this header file in 2 different .cpp files.现在#include这个 header 文件在 2 个不同的.cpp文件中。 In both of them try to call foo() with object of X .在他们两个中尝试使用X的 object 调用foo() It will print:它将打印:

a = 0
a = 0

Which means that X::foo() in both the .cpp files are different .这意味着两个.cpp文件中X::foo()是不同的。 If you give the namespace a name and repeat the same thing, it will output如果你给namespace一个名字并重复同样的事情,它会 output

a = 0
a = 1

Thus unnamed namespace creates a different copy for each translation unit.因此,未命名的命名namespace会为每个翻译单元创建不同的副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实现匿名命名空间中声明的 function 时出现未定义引用 linker 错误 - Undefined reference linker error when implementing function declared in anonymous namespace 在匿名命名空间和外部定义静态函数之间有什么不同吗? - Is there any diference between defining static function inside anonymous namespace and outside? 找不到在未命名的命名空间内声明的函数的函数定义 - 如何解决? (Visual Studio 2015) - Function definition not found for a function declared inside unnamed namespace - how to resolve? (Visual Studio 2015) 警告定义在命名空间内声明的友元运算符 - warning defining friend operator declared inside a namespace 在匿名命名空间中引用前向声明的 function? - Referencing forward-declared function in anonymous namespace? 找不到在未命名命名空间中声明的 >>() 和 <<() - Cannot find >>() and <<() declared in unnamed namespace 匿名命名空间内的自由函数 - free function inside anonymous namespace 如果在匿名命名空间中声明函数,是否可以在全局命名空间中定义函数? - Can a function be defined in global namespace if it is declared in an anonymous namespace? 在结构中定义声明的成员 function - Defining declared member function inside struct 在匿名命名空间内定义 QObject 派生类? - Define a QObject derived class inside an anonymous namespace?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM