C++ 在非成员交换()方面实现成员交换()

C++ 在非成员交换()方面实现成员交换(),c++,c++17,swap,overload-resolution,argument-dependent-lookup,C++,C++17,Swap,Overload Resolution,Argument Dependent Lookup,我正在实现一个类,该类的接口与std::array类似,它同时具有和 因为我希望我的类模仿标准容器,所以我想实现两种swap()(非成员swap()是通过ADL实现的,因为不允许专门化std::swap()): A类{ 公众: 朋友无效交换(A&A,A&b){/*交换东西*/} 无效交换(A和其他){swap(*this,other);} }; 但是,似乎我无法从类内部调用非成员swap(),因为它更喜欢成员swap(),即使它只有一个参数。将其更改为::swap(*this,other)也不

我正在实现一个类,该类的接口与
std::array
类似,它同时具有和

因为我希望我的类模仿标准容器,所以我想实现两种
swap()
(非成员
swap()
是通过ADL实现的,因为不允许专门化
std::swap()
):

A类{
公众:
朋友无效交换(A&A,A&b){/*交换东西*/}
无效交换(A和其他){swap(*this,other);}
};

但是,似乎我无法从类内部调用非成员
swap()
,因为它更喜欢成员
swap()
,即使它只有一个参数。将其更改为
::swap(*this,other)
也不起作用,因为类内友元函数只能通过ADL查找。如何从类内部调用非成员的
swap()

#包括
#包括
甲级{
公众:

朋友无效掉期(A&A、A&b){std::cout问题是成员函数的名称
swap
A::swap
的主体中隐藏了命名空间范围
swap
。在
A::swap
中对
swap
进行非限定名称查找将永远找不到命名空间范围
swap
,因此,命名空间范围
swap
将不是o的一部分f重载集。解决此问题的一种方法是在
a::swap
的主体中添加命名空间范围
swap
的声明:

A类
{
公众:
朋友无效交换(A&A,A&b){/*交换东西*/}
无效掉期(A和其他)
{
无效掉期(A&A、A&b);
掉期(*本,其他);
}
};

话虽如此,但我不确定这对您真正有什么作用。显而易见的解决方案是只根据
A::swap
实现名称空间范围
swap
,而不是反过来。就个人而言,我不会从
swap
成员函数开始。
A
b
只是
swap(a,b)
..

您可以先声明类和交换函数,然后在成员函数中使用全局名称空间说明符

现在,您可以在类外自由定义交换函数

#包括
#包括
甲级;
无效掉期(A&A、A&b);
甲级{
内特的东西;
公众:
A(inta):东西(A){
朋友无效掉期(A&A、A&b);

void print_stuff(){std::cout为什么不在成员
swap
方面实现非成员
swap
?@Evg我可以,但是非成员
swap
的对称性看起来更好。为什么要在友元函数
void swap(A&A,A&b)中添加交换的实现
?它应该属于一个成员函数,如
无效交换(a和其他)
无效交换(a和a,a和b)
,然后可以调用成员函数。此外,如果使用正确的方法(使用成员实现非成员),您不需要非成员是类的朋友。您显然是在制造问题…@Phil1970您是否有参考资料表明使用成员实现非成员是正确的方法?请注意,问题中的朋友
swap
可以从成为类的朋友中获益。可能值得一提的是,为什么要求(不可自定义!)
std::swap
查找隐藏的好友。如果您的设计鼓励块作用域函数声明,则说明您做得不对。
//> A's stuff is 1
//> Friend swap
//> A's stuff is 2