如何获得广义互换功能?
使用std ::交换的示例 cppreference 我尝试了以下交换
-template:
#include <algorithm>
#include <iostream>
namespace Ns
{
class A
{
int id{};
friend void swap(A& lhs, A& rhs)
{
std::cout << "swap(" << lhs << ", " << rhs << ")\n";
std::swap(lhs.id, rhs.id);
}
friend std::ostream& operator<< (std::ostream& os, A const& a)
{
return os << "A::id=" << a.id;
}
public:
A(int i) : id{i} { }
A(A const&) = delete;
A& operator = (A const&) = delete;
};
}
template<typename T> void SWAP(T &l, T &r)
{
try { std::swap(l, r); }
catch(...) { swap(l, r); }
}
int main()
{
std::cout << "\n======================\n";
int a = 5, b = 3;
std::cout << "before: " << a << ' ' << b << '\n';
std::swap(a,b);
std::cout << "after: " << a << ' ' << b << '\n';
std::cout << "\n=========\n";
Ns::A p{6}, q{9};
std::cout << "before: " << p << ' ' << q << '\n';
// std::swap(p, q); // error, type requirements are not satisfied
swap(p, q); // OK, ADL finds the appropriate friend `swap`
std::cout << "after: " << p << ' ' << q << '\n';
std::cout << "\n======================\n";
std::cout << "before: " << a << ' ' << b << '\n';
SWAP(a,b);
std::cout << "after: " << a << ' ' << b << '\n';
std::cout << "\n=========\n";
std::cout << "before: " << p << ' ' << q << '\n';
SWAP(p, q);
std::cout << "after: " << p << ' ' << q << '\n';
}
处理名称空间中的“朋友”交换函数;只需一个单个交换函数即可处理所有情况。
compiler-error:在此范围中未声明
为什么在main
中调用swap()
在模板中工作。 ?
是否有一种方法可以使用广义的“交换”功能来处理所有此类情况?
(编辑)
感谢@rici对模板的以下更改的作用:
template<typename T> void SWAP(T &l, T &r)
{
using namespace std;
swap(l, r);
}
对于我的问题的第一部分,我仍然感谢ELI5:什么/为什么/为什么工作...
Using the example for std::swap on cppreference I tried the following SWAP
-template:
#include <algorithm>
#include <iostream>
namespace Ns
{
class A
{
int id{};
friend void swap(A& lhs, A& rhs)
{
std::cout << "swap(" << lhs << ", " << rhs << ")\n";
std::swap(lhs.id, rhs.id);
}
friend std::ostream& operator<< (std::ostream& os, A const& a)
{
return os << "A::id=" << a.id;
}
public:
A(int i) : id{i} { }
A(A const&) = delete;
A& operator = (A const&) = delete;
};
}
template<typename T> void SWAP(T &l, T &r)
{
try { std::swap(l, r); }
catch(...) { swap(l, r); }
}
int main()
{
std::cout << "\n======================\n";
int a = 5, b = 3;
std::cout << "before: " << a << ' ' << b << '\n';
std::swap(a,b);
std::cout << "after: " << a << ' ' << b << '\n';
std::cout << "\n=========\n";
Ns::A p{6}, q{9};
std::cout << "before: " << p << ' ' << q << '\n';
// std::swap(p, q); // error, type requirements are not satisfied
swap(p, q); // OK, ADL finds the appropriate friend `swap`
std::cout << "after: " << p << ' ' << q << '\n';
std::cout << "\n======================\n";
std::cout << "before: " << a << ' ' << b << '\n';
SWAP(a,b);
std::cout << "after: " << a << ' ' << b << '\n';
std::cout << "\n=========\n";
std::cout << "before: " << p << ' ' << q << '\n';
SWAP(p, q);
std::cout << "after: " << p << ' ' << q << '\n';
}
to handle the 'friend' swap-function in the namespace; to have just a single SWAP function to call that will handle all cases.
The compiler-error: swap was not declared in this scope
Why does calling swap()
for the namespace work in main
but not in the template?
and is there a way to have a generalized 'SWAP'-function to handle all such cases?
(edit)
Thanks to @rici the following change to the template works:
template<typename T> void SWAP(T &l, T &r)
{
using namespace std;
swap(l, r);
}
I would still appreciate an ELI5 for the first part of my question: what/how/why does this work ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有两个问题。
请首先阅读'std ::交换'的定义'在这里。
您将阅读该类型的要求。
您定义了(删除)构造函数和分配操作员。这样,编译器将不会为您创建标准的构造函数/分配运算符。请阅读有关5规则的信息。
您的班级不再是 moveAssignable 和 moveconstructiblesible 。
只需删除已删除的操作员和构造函数即可。
像下面一样。然后它将编译。
There are 2 problems.
Please first read the definition of 'std::swap' here.
You will read the requirements for the type.
You defined (deleted) a constructor and assign operator. With that the compiler will not create the standard constructors/assign operators for you. Please read about the rule of 5.
Your class is no longer MoveAssignable and MoveConstructible.
Simply remove the deleted operator and constructor.
Like the below. Then it will compile.