Sea*_*ean 14 c++ scope namespaces
我的困惑来自"C++ Primer 5th edition"第13.3节,第518页.
非常仔细的读者可能想知道为什么
using里面的声明swap不会隐藏HasPtr版本的声明swap.
我试图阅读它的参考但仍然不明白为什么.有人可以解释一下吗?谢谢.这是问题的代码示例.
假设类Foo有一个名为的成员h,它具有类型HasPtr.
void swap(HasPtr &lhs, HasPtr &rhs)
{...}
void swap(Foo &lhs, Foo &rhs)
{
using std::swap;
swap(lhs.h, rhs.h);
}
Run Code Online (Sandbox Code Playgroud)
为什么swap对于HasPtr没有隐藏这似乎在外部范围中声明,而using std::swap在内部范围?谢谢.
mol*_*ilo 10
由于using std::swap;并不意味着"从今以后,每一个'交换’应该用std::swap",而是"带来的所有重载swap从std到目前的范围".
在这种情况下,效果与您using namespace std;在函数内部编写的效果相同.
在using声明 using std::swap并不能掩盖你声明交换的功能HasPtr和Foo.它带来的名字swap形成了std命名空间声明区.有了它,std::swap可以参与重载决议.
从C++ 11标准:
7.3.3使用声明
1 using声明在声明区域中引入了一个名称,其中出现了using声明.
using声明:
using typenameopt nested-name-specifier unqualified-id;
using ::不合格的;using声明中指定的成员名称在using声明出现的声明区域中声明.[ 注意:只声明指定的名称; 在using-declaration中指定枚举名称不会在using-declaration的声明性区域中声明其枚举数.-end note ]如果using声明命名一个构造函数(3.4.3.1),它会隐式声明出现using-declaration的类中的一组构造函数(12.9); 否则,using-declaration中指定的名称是在其他地方声明的某个实体的名称的同义词.
在您的情况下,您有:
void swap(Foo &lhs, Foo &rhs)
{
using std::swap;
swap(lhs.h, rhs.h);
}
Run Code Online (Sandbox Code Playgroud)
该using std::swap;声明引入的名字swap从std命名空间到声明性区域,这是身体swap(Foo&, Foo&)功能.这个名字swap来自全局命名空间仍然是在函数体访问.
如果您发布的是整个函数,那么您不需要using std::swap声明.你可以通过以下方式得到:
void swap(Foo &lhs, Foo &rhs)
{
swap(lhs.h, rhs.h);
}
Run Code Online (Sandbox Code Playgroud)
因为swap(HasPtr &lhs, HasPtr &rhs)从功能可见.
现在,看看下面的例子.
struct Bar {};
void swap(Bar& lhs, Bar& rhs)
{
}
struct Foo
{
int a;
Bar b;
};
void swap(Foo& lhs, Foo& rhs)
{
swap(lhs.a, rhs.a); // A problem
swap(lhs.b, rhs.b);
}
Run Code Online (Sandbox Code Playgroud)
标记的行A problem是一个问题,因为没有名为的函数swap可以使用两个类型的对象int&作为参数.您可以使用以下方法之一解决此问题:
std::swap明确使用.
void swap(Foo& lhs, Foo& rhs)
{
std::swap(lhs.a, rhs.a);
swap(lhs.b, rhs.b);
}
Run Code Online (Sandbox Code Playgroud)介绍std::swap这个功能.
void swap(Foo& lhs, Foo& rhs)
{
using std::swap;
swap(lhs.a, rhs.a);
swap(lhs.b, rhs.b);
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
1163 次 |
| 最近记录: |