背景:
我正在尝试实现一个函数,让我们称之为mysort
,它接受相同类型的可变数量的参数并对其进行排序。例如,下面的代码应该打印1 2 3
template <typename ... Args>
void mysort(Args& ... args);
int main(int, char**)
{
int x = 3;
int y = 1;
int z = 2;
mysort(x, y, z);
cout << x << ' ' << y << ' ' << z << endl;
return 0;
}
我尝试过的:
下面是我想出的解决方案
#include <array>
#include <algorithm>
#include <functional>
template <typename T, typename ... Args>
void mysort(T& t, Args& ... args)
{
constexpr size_t n = sizeof...(Args) + 1;
std::array<std::reference_wrapper<T>, n> temp = { std::ref(t), std::ref(args)... };
std::sort(temp.begin(), temp.end());
}
但是这个解决方案不起作用,因为std::swap
对std::reference_wrapper
所做的不是我所期望的(我期望对std::reference_wrapper
的任何更改都应该更改为其创建std::reference_wrapper
的对象)。
在adding之后,一切都开始工作
namespace std
{
void swap(std::reference_wrapper<int>& a, std::reference_wrapper<int>& b) noexcept
{
std::swap(a.get(), b.get());
}
}
我不确定标准是否要求std::sort
使用std::swap
,所以我认为这不是一个完整的解决方案,并且依赖于实现。
汇总:
我对std::reference_wrapper的想法是,它应该像引用一样工作,但情况似乎并非如此。以下是我的问题:
1.什么是实现mysort
的最佳方法?
1.为什么标准没有为std::reference_wrapper
提供交换底层对象的std::swap
规范?
提前感谢您的回答!
2条答案
按热度按时间ztyzrc3y1#
std::reference_wrapper
的要点是它是可复制和可赋值的,“可赋值”的意思是引用 Package 器可以以普通引用不能的方式反弹到新值。你在做与它的本意相反的事情。在您的例子中,当
std::sort
的实现交换临时数组中的项时,它重新绑定了引用,但这不是您想要的。您希望它交换实际的项而不是引用。一种方法是让
std::sort
对参数的副本进行排序,然后将它们按排序顺序分配回引用参数:在这里,我将它们 Package 在一个元组中,以便可以通过
std::tie
进行赋值。可能有一些方法可以用更少的副本来做到这一点,但这是我想到的。5sxhfpxr2#
基本上,
std::reference_wrapper
是一个旧的设计不佳的类,目前用于某些简单的目的,如在std::bind/bind_front
或std::thread
的构造中,它用于暗示变量不是复制的,而是通过引用获取的。然后通过std::ref/cref
创建它们。我只是不建议使用
std::reference_wrapper
,除了模板情况下,它用于区分用户是想要转发对象的副本还是引用。如果你想要一个模仿引用的类来执行赋值/移动,而不是重新绑定,那就由你来实现了。只是你应该意识到在某些情况下可能会有问题。
也不要写任何
它可能会破坏您导入的大量代码。