为什么在全局命名空间中没有std :: swap?

时间:2013-10-25 11:04:17

标签: c++ swap

Effective c++ third edition中的第25项,Scott Meyers建议在与类相同的命名空间中实现swap,然后在交换时使用使用std :: swap,然后作者说:

  

例如,如果你用这种方式写调用swap:

std::swap(obj1,obj2);  // the wrong way to call swap
     

你强迫编译器只考虑std中的swap   消除了获得更合适的特定T的可能性   其他地方的版本。唉,一些被误导的程序员确实有资格   以这种方式调用交换,这就是为什么它完全重要   为你的类专门化std :: swap。

作者建议始终以这种方式交换对象:

#include <iostream>
#include <utility>

#define CUSTOM_SWAP

namespace aaa{

struct A
{
};
#ifdef CUSTOM_SWAP
void swap( A&, A& )
{
    std::cout<<"not std::swap"<<std::endl;
}
#endif

}

int main() 
{
    using std::swap;   // add std::swap to a list of possible resolutions

    aaa::A a1;
    aaa::A a2;

    swap(a1,a2);
}

为什么全局命名空间中没有std::swap?这样,添加自定义交换功能会更简单。

1 个答案:

答案 0 :(得分:4)

可能是因为标准是这样说的,17.6.1.1/2:

  

除了宏,operator new和operator delete之外的所有库实体都在命名空间std中命名,命名空间std中嵌套了名称空间。

你有时候还需要放using ::swap,所以它会引入更多特殊情况。在这里,我使用func代替swap - http://ideone.com/WAWBfZ

#include <iostream>
using namespace std;

template <class T>
auto func(T) -> void
{
cout << "::f" << endl;
}

namespace my_ns {
struct my_struct {};

auto func(my_struct) -> void
{
cout << "my_ns::func" << endl;
}

auto another_func() -> void
{
// won't compile without `using ::func;`
func(123);
}
}

auto main() -> int {}

失败
prog.cpp: In function ‘void my_ns::another_func()’:
prog.cpp:21:17: error: could not convert ‘123’ from ‘int’ to ‘my_ns::my_struct’
         func(123);