【发布时间】:2010-11-15 17:35:43
【问题描述】:
什么是 C++ 中的“命名空间别名”?它是如何使用的?
【问题讨论】:
标签: c++ namespaces
什么是 C++ 中的“命名空间别名”?它是如何使用的?
【问题讨论】:
标签: c++ namespaces
命名空间用于防止名称冲突。
例如:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
您现在有两个类名称栏,由于命名空间,它们完全不同且分开。
您展示的“使用命名空间”是为了让您不必指定命名空间即可使用该命名空间中的类。即 std::string 变为字符串。
我的资源:@987654321@
【讨论】:
还要注意命名空间别名和 using 指令是在编译时解析的,而不是在运行时解析的。 (更具体地说,它们都是用于告诉编译器在解析名称时在哪里寻找其他工具,如果它无法在当前范围或其任何父范围中找到特定符号。)例如,这些都不会编译:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
现在,好奇的人可能已经注意到constexpr 变量也在编译时使用,并且想知道它们是否可以与别名或指令一起使用。据我所知,他们不能,尽管我可能错了。如果您需要在不同命名空间中使用同名变量,并在它们之间动态选择,则必须使用引用或指针。
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
上面的用处可能有限,但应该能达到目的。
(对于我在上面可能遗漏的任何错别字,我深表歉意。)
【讨论】:
这就是为 looong 命名空间名称选择别名,例如:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
然后,你可以键入def
typedef SHORT::mytype
而不是
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
此语法仅适用于命名空间,不能包含类、namespace NAME = 之后的类型
【讨论】:
很简单,#define 不起作用。
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
编译正常。让您可以解决命名空间/类名冲突。
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
在最后一行,“Hmm:Oops”是一个编译错误。预处理器将其更改为 Nope::Oops,但 Nope 已经是一个类名。
【讨论】:
命名空间别名是一种通过不同的较短名称来引用长命名空间名称的便捷方式。
例如,假设您想使用 Boost 的 uBLAS 中的数字向量,而无需 using namespace 指令。每次都说明完整的命名空间很麻烦:
boost::numeric::ublas::vector<double> v;
相反,您可以为boost::numeric::ublas 定义一个别名——假设我们想将其缩写为ublas:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
【讨论】: