C++ (匿名)名称空间、函数和头文件

C++ (匿名)名称空间、函数和头文件,c++,function,namespaces,C++,Function,Namespaces,不确定以前是否有人问过这个问题。我四处搜索,找不到我的情景的确切答案,但我可能错过了 问题:我在头文件中有一个名称空间,在头文件中该名称空间中有一些函数原型: namespace Foo{ void SomeFunc(); void SomeOtherFunc(int); } 在.cpp文件中,我想在名称空间中定义函数,同时为它们所依赖的匿名名称空间的随机数生成器提供一些保护: namespace Foo{ namespace{ RNG rando =

不确定以前是否有人问过这个问题。我四处搜索,找不到我的情景的确切答案,但我可能错过了

问题:我在头文件中有一个名称空间,在头文件中该名称空间中有一些函数原型:

namespace Foo{
    void SomeFunc();
    void SomeOtherFunc(int);
}
在.cpp文件中,我想在名称空间中定义函数,同时为它们所依赖的匿名名称空间的随机数生成器提供一些保护:

namespace Foo{

    namespace{
        RNG rando = new RNG();
    }

    void SomeFunc(){
        //implementation
    }

    void SomeOtherFunc(){
        //implementation
    }
}
namespace{
    RNG rando = new RNG();
}

void Foo::SomeFunc(){
    //implementation
}

void Foo::SomeOtherFunc(int){
    //implementation
}
我遇到的问题是,无法保证头文件中的原型与我在cpp文件中定义的函数匹配。命名空间{}代码块中的所有内容都可以是新添加到命名空间中的内容

在上面的代码示例中,SomeOtherFunc()是在没有int类型参数的情况下实现的,但其声明表示它需要一些参数。实际上,似乎我重载了SomeOtherFunc()签名

我可以在cpp文件中使用以下内容:

namespace Foo{

    namespace{
        RNG rando = new RNG();
    }

}
void Foo::SomeFunc(){
    //implementation
}

void Foo::SomeOtherFunc(int){
    //implementation
}
编译器似乎加强了函数声明和实现之间的关系,这是我喜欢的。但是这些函数似乎无法访问匿名名称空间中的数据


我是不是遗漏了什么?我能做些什么来解决我觉得在这个实现中存在的问题吗?我不太熟悉使用(匿名)名称空间,因此如果这看起来很基本,我很抱歉。

将未命名的名称空间移出其他名称空间:

namespace Foo{

    namespace{
        RNG rando = new RNG();
    }

    void SomeFunc(){
        //implementation
    }

    void SomeOtherFunc(){
        //implementation
    }
}
namespace{
    RNG rando = new RNG();
}

void Foo::SomeFunc(){
    //implementation
}

void Foo::SomeOtherFunc(int){
    //implementation
}

无论如何都不能在翻译单元之外访问它。

将未命名的命名空间移出其他命名空间:

namespace Foo{

    namespace{
        RNG rando = new RNG();
    }

    void SomeFunc(){
        //implementation
    }

    void SomeOtherFunc(){
        //implementation
    }
}
namespace{
    RNG rando = new RNG();
}

void Foo::SomeFunc(){
    //implementation
}

void Foo::SomeOtherFunc(int){
    //implementation
}

无论如何,在翻译单元之外都无法访问它。

匿名名称空间是一种转移注意力的方法。您可以忽略它,它实际上是一个实现细节


是的,您可以从.cpp文件的头中重载函数。但是,如果您试图使用该对中未定义的那一半,则会出现链接器错误。

匿名名称空间是个麻烦。您可以忽略它,它实际上是一个实现细节


是的,您可以从.cpp文件的头中重载函数。但是,如果您试图使用该对中未定义的那一半,则会出现链接器错误。

据我所知,通常的约定是在.cpp文件的开头声明匿名名称空间。在您的情况下,您的cpp文件应该如下所示

namespace{
   RNG rando = new RNG();
}

void Foo::SomeFunc(){
    //implementation
}

void Foo::SomeOtherFunc(int){
    //implementation
}

通过这种方式,函数应该可以访问rando。

据我所知,通常的约定是在.cpp文件的开头声明匿名名称空间。在您的情况下,您的cpp文件应该如下所示

namespace{
   RNG rando = new RNG();
}

void Foo::SomeFunc(){
    //implementation
}

void Foo::SomeOtherFunc(int){
    //implementation
}

通过这种方式,这些函数应该可以访问rando。

太棒了,感谢您的快速响应。我想就是这样,但昨晚我分心了,没有机会检查。所以我想我会在工作的午休时间问你。太棒了,谢谢你的快速回复。我想就是这样,但昨晚我分心了,没有机会检查。所以我想在我工作的午餐休息时间,我会在这里问一下。