C++ 如何在扩展名称空间之间共享作用域?

C++ 如何在扩展名称空间之间共享作用域?,c++,compiler-errors,namespaces,C++,Compiler Errors,Namespaces,请看下面的代码。首先,创建一个包含类的名称空间。然后,扩展名称空间并使用我们之前定义的类。这是一本书 在gcc 4.8.1下编译此文件时,如果没有permissive标志,将产生两个编译器错误。明确地提到像system::module这样的名称空间可以解决问题,即使它与我们已经使用的名称空间相同 error: declaration of ‘system::module* system::entry::module’ [-fpermissive] module *module;

请看下面的代码。首先,创建一个包含类的名称空间。然后,扩展名称空间并使用我们之前定义的类。这是一本书

在gcc 4.8.1下编译此文件时,如果没有permissive标志,将产生两个编译器错误。明确地提到像
system::module
这样的名称空间可以解决问题,即使它与我们已经使用的名称空间相同

error: declaration of ‘system::module* system::entry::module’ [-fpermissive]
    module *module;
            ^
error: changes meaning of ‘module’ from ‘class system::module’ [-fpermissive]
   class module {
         ^
为什么该规范不符合标准?除了每次都明确提到名称空间之外,我还有什么其他选择。

在这句话中

module *module;
您重新定义了名称模块

因此,在成员函数声明中,必须使用详细的类型名称

entry( class module *module);

无论如何,以这种方式重新定义名称是个坏主意。

正如在另一个答案中已经指出的,编译器正在抱怨您将标识符的语义从类型更改为变量名(
模块

您应该为类型指定一个名称,使其易于与变量区分开来。您应该为成员变量提供易于与常规变量区分的名称。这提高了代码的可读性和可维护性。而且,它的副作用是使你面临的问题成为一个非问题:

// File one
namespace system {
    class module_type {
        // ...
    };
}

// File two including file one
namespace system {
    struct entry {
        entry(module_type *module);
        module_type *module_;
    };
}
我真的无法想出更具描述性的名字

命名是程序员面临的最困难的挑战之一,然而,当显示一种方式(或2或n)时,它将永远更容易

我提供了以下内容-根据我长期使用的编码标准

class and namespace names are Capitalized, at least the 1st char

variable names are lower case (or camel case with lower case 1st char)


// File one
namespace System {
    class Module {
        // ...
    };
}

// File two including file one
namespace System {
    struct Entry {
        Entry(Module* module);
        Module* module;
    };
}
那么


搜索并阅读一些编码标准。它们的存在是有原因的。一旦你学会了一个好主意,它将为你的职业生涯服务。

你确定要将变量命名为与其类名相同的名称吗?@jxh是的,我想这样做,因为这是我应用程序中非常抽象的一部分,我真的无法想出更具描述性的名称。但是,我可以给变量加前缀,比如
\u module
。你能给我这样做的建议吗?可能是后缀
\uu
,或者使用
m
前缀更为标准。您希望以某种方式区分变量名和类型名,以使代码更易于阅读。也许可以大写您的类型名。@jxh我决定不使用title case类名,以符合标准库的下划线case约定。用下划线后固定成员听起来很合理。但是,如何区分局部变量、类型和名称空间?这似乎把事情复杂化了。可能有一个gcc标志只允许这种行为,但不允许
-fpPermission
所暗示的一切。我想你需要问问自己,为什么你要编写让别人看不懂的代码。目前,我对类和实例使用相同的名称,有时甚至对包装类的命名空间也使用相同的名称。既然我想使用下划线,那么标准库是如何解决这个问题的呢?像
namespace\u module
@danijar这样的语义让人觉得很傻,你可以用相同的名称命名一个名称空间和一个类。但是,当您使用与类相同的名称命名对象时,对象名称会隐藏类的名称,并且您必须为类(或枚举)使用详细的类型名称。然而,现在我想坚持标准的库约定。所以一切都是小写的。您知道标准库是如何做到这一点的吗?@danijar-曾经有一段时间,供应商提供的库使用双下划线(后缀或前缀)来保持其符号的唯一性,并停止对用户符号的干扰。当然,这只会鼓励一些用户使用双下划线,因为他们只是遵循供应商的选择。换句话说,IMHO,标准库约定适用于标准库,而不是您的个人库。请咨询您的质量保证部门、团队负责人或教授。祝你好运哦,不,我不知道其他人是如何处理这个问题的……你会问标准库是如何处理这个问题的。这是特定于实现的,每个供应商的做法都不同。如果您看一下libstdc++的GNU版本,您肯定会看到它们将标准类型名称包装在其实现之上。它们的实现使用一种编码约定,允许它们区分类型名和变量名,以及成员变量和常规变量。
// File one
namespace system {
    class module {
        // ...
    };
}

// File two including file one
namespace system {
    struct entry {
        entry(module *module);
        module *module;
    };
}
class and namespace names are Capitalized, at least the 1st char

variable names are lower case (or camel case with lower case 1st char)


// File one
namespace System {
    class Module {
        // ...
    };
}

// File two including file one
namespace System {
    struct Entry {
        Entry(Module* module);
        Module* module;
    };
}