为什么;使用名称空间X&引用;不允许在类/结构级别内使用? < > > >编辑< /强>:想知道它背后的动机。< p>因为C++标准明确禁止。来自C++03§7.3.4[名称空间.udir]: class C { using namespace std; // error }; namespace N { using namespace std; // ok } int main () { using namespace std; // ok } 使用指令: 使用namespace::opt嵌套名称说明符opt namespace name;
using指令不应出现在类范围内,但可以出现在命名空间范围或块范围内。[注意:在using指令中查找名称空间名称时,只考虑名称空间名称,请参见3.4.6。]为什么;使用名称空间X&引用;不允许在类/结构级别内使用? < > > >编辑< /强>:想知道它背后的动机。< p>因为C++标准明确禁止。来自C++03§7.3.4[名称空间.udir]: class C { using namespace std; // error }; namespace N { using namespace std; // ok } int main () { using namespace std; // ok } 使用指令: 使用namespace::opt嵌套名称说明符opt namespace name;,c++,namespaces,using,language-lawyer,C++,Namespaces,Using,Language Lawyer,using指令不应出现在类范围内,但可以出现在命名空间范围或块范围内。[注意:在using指令中查找名称空间名称时,只考虑名称空间名称,请参见3.4.6。] 为什么C++标准禁止它呢?我不知道,问问批准语言标准的ISO委员会的一位成员。我不太清楚,但我猜在类范围内允许这样做可能会引起混淆: using-directive: using namespace ::opt nested-name-specifieropt namespace-name ; 因为没有明显的方法可以做到这一点,标准
为什么C++标准禁止它呢?我不知道,问问批准语言标准的ISO委员会的一位成员。我不太清楚,但我猜在类范围内允许这样做可能会引起混淆: using-directive: using namespace ::opt nested-name-specifieropt namespace-name ; 因为没有明显的方法可以做到这一点,标准只是说你不能 现在,当我们讨论名称空间范围时,这就不那么令人困惑了:
namespace Hello
{
typedef int World;
}
class Blah
{
using namespace Hello;
public:
World DoSomething();
}
//Should this be just World or Hello::World ?
World Blah::DoSomething()
{
//Is the using namespace valid in here?
}
我相信理由是,这可能会令人困惑。当前,在处理类级标识符时,查找将首先在类范围中搜索,然后在封闭的命名空间中搜索。允许
在类级别使用名称空间
,将对现在如何执行查找产生相当大的副作用。特别是,它必须在检查特定类范围和检查封闭命名空间之间的某个时间执行。即:1)合并类级别和已用命名空间级别的查找,2)在类范围之后但在任何其他类范围之前查找已用命名空间,3)在封闭命名空间之前查找已用命名空间。4) 查找与封闭的命名空间合并
名称空间A{
void foo(int){std::cout我认为这是该语言的一个缺陷。您可以使用下面的解决方法。记住这个解决方法,在语言更改的情况下,很容易建议名称冲突解决规则
namespace A {
void foo( int ) { std::cout << "int"; }
}
void foo( double ) { std::cout << "double"; }
struct test {
using namespace A;
void f() {
foo( 5.0 ); // would print "int" if A is checked *before* the
// enclosing namespace
}
};
这可能是不允许的,因为开放性与封闭性。
类和结构在C++中始终是封闭的实体。它们在一个地方被定义(虽然可以拆分声明和实现)。
- 名称空间可以经常任意打开、重新打开和扩展
将名称空间导入类会导致以下有趣的情况:
namespace Foo{}
结构条{使用名称空间Foo;};
名称空间Foo{
使用Baz=int;//我刚刚用一个类型别名扩展了'Bar'!
void baz();//我刚刚用一个看起来像静态函数的函数扩展了'Bar'!
//等等。
}
@pst:C#没有类似于使用名称空间的功能。C#允许类似的功能,但仅限于文件范围。C++的使用名称空间
允许您将一个名称空间合并到另一个名称空间。重复?@ZachSaw,我理解您的担忧。我已尝试根据相关性关闭Qn。因为这篇文章包含更多的ob客观的回答和参考标准,我一直保持开放。过去,我的许多旧Qn被新Qn关闭。有时被我关闭,有时被其他人关闭。如果你觉得这个决定不合适,请向钻石Mods发出信号。没有怨言。:-@iammilind不在乎TBH。这几天一团糟。但是标记一个帖子ch以“我不清楚”开头,因为答案实际上包含“更客观的答案&参考标准”。哈哈。@ZachSaw,我不仅仅是在谈论被接受的答案,而是整个帖子。是的,它是客观的,但标准引用包含在中。它以“我不知道”开头,因为即使在标准中,也没有理由解释为什么“使用命名空间"不允许在<代码>类/结构> /代码>内。它只是不允许的。但是被接受的答案确实讨论了不允许它的逻辑理由。即在哪里考虑“代码> hello:世界< /代码>以及在哪里考虑<代码> Word < /代码>。希望澄清疑惑。+ 1,我想到这个原因,但同样的事情适用于<代码>。>在其他名称空间中使用名称空间Hello;
(并在其内部声明extern
函数)我不认为它是混乱的。C++不是猜测。如果允许,那么C++ ISO委员会就可以在语言规范中指定。否则你不会说它是混乱的。否则人们可能会说这是令人困惑的:但是,这样的编码规则在SPE.@纳瓦兹:大多数用户的语言中都是指定的。我从来没有。“C++”是关于猜测的。我是说,当设计规范时,它设计的是大多数程序员提前预期的行为。而纸上的规则常常是混乱的——标准试图明确,但并不总是成功。在第一个例子中,应该是:<代码> hello:世界::
或Blah::World Blah::DoSomething()
namespace A {
void foo() {}
struct B {
struct foo {};
void f() {
foo(); // value initialize a A::B::foo object (current behavior)
}
};
}
struct C {
using namespace A;
struct foo {};
void f() {
foo(); // call A::foo
}
};
namespace A {
void foo() {}
}
void bar() {}
struct base {
void foo();
void bar();
};
struct test : base {
using namespace A;
void f() {
foo(); // A::foo()
bar(); // base::bar()
}
};
namespace A {
void foo( int ) { std::cout << "int"; }
}
void foo( double ) { std::cout << "double"; }
struct test {
using namespace A;
void f() {
foo( 5.0 ); // would print "int" if A is checked *before* the
// enclosing namespace
}
};
namespace Hello
{
typedef int World;
}
// surround the class (where we want to use namespace Hello)
// by auxiliary namespace (but don't use anonymous namespaces in h-files)
namespace Blah_namesp {
using namespace Hello;
class Blah
{
public:
World DoSomething1();
World DoSomething2();
World DoSomething3();
};
World Blah::DoSomething1()
{
}
} // namespace Blah_namesp
// "extract" class from auxiliary namespace
using Blah_namesp::Blah;
Hello::World Blah::DoSomething2()
{
}
auto Blah::DoSomething3() -> World
{
}