是否有一种很好的方法可以将STD :: Minmax(A,B)分配给STD :: TIE(A,B)
Is there a nice way to assign std::minmax(a, b) to std::tie(a, b)?
std::tie(a, b) = std::minmax(a, b);
我认为这是直观的代码。干净和可理解。太糟糕了,它无法正常工作,就像std::minmax
模板const&
一样。因此,如果值交换在std::pair<const&, const&>
内,则与一个分配相比将覆盖另一个值:
auto[a, b] = std::make_pair(7, 5);
std::tie(a, b) = std::minmax(a, b);
std::cout << "a: " << a << ", b: " << b << 'n';
a:5,b:5
这里的预期输出是a: 5, b: 7
。
我认为这很重要,因为实施转换功能以将功能应用于某些范围需要直观的lambdas陈述。例如:
std::vector<int> v{ 0, 1, 0, 2, 0 };
std::vector<int> u{ 1, 0, 1, 0, 1 };
perform(v.begin(), v.end(), u.begin(), [](auto& a, auto& b){
std::tie(a, b) = std::minmax(a, b);
});
//v would be == {0, 0, 0, 0, 0}
//u would be == {1, 1, 1, 2, 1}
我发现的一种解决方案是在std::pair<const&, const&>
上明确构建std::tuple
,没有任何参考预选赛来强制执行副本:
std::tie(a, b) = std::tuple<int, int>(std::minmax(a, b));
但是,这种<int, int>
冗余似乎很糟糕,尤其是在以前说过auto& a, auto& b
时。
是否有一个很好的方法可以执行此任务?难道这是错误的方向,只是说if (a >= b) { std::swap(a, b); }
是这里最好的方法吗?
您可以使用 minmax
的初始化列表:
std::tie(a, b) = std::minmax({a, b});
这会导致创建临时对象,就像使用 unary plus 时一样,但它的好处是它与缺少 Unary plus plus 操作员的类型一起工作。
using namespace std::string_view_literals;
auto [a, b] = std::make_pair("foo"sv, "bar"sv);
std::tie(a, b) = std::minmax({a, b});
std::cout << "a: " << a << ", b: " << b << 'n';
输出:
a: bar, b: foo
这可能是错误的方向,只是说
if (a >= b) { std::swap(a, b); }
是这里最好的方法吗?
由于比较 1 要求,我会将其制作if(b < a) std::swap(a, b);
,但是,是的,我怀疑这会更快,而且仍然很清楚您想完成的工作。
[1]
您可以用以下一定级别的简短执行此操作。
std::tie(a, b) = std::minmax(+a, +b);
std::cout << "a: " << a << ", b: " << b << 'n';
说明:为了对称性,内置的Unary Plus运算符与其单位减兄弟姐妹,通过Value 返回其操作数(它也执行通常的算术转换,但这不适用于int
s(。这意味着它必须创建一个临时性,即使此临时性不过是操作数的副本。但是对于在此示例中使用minmax
,这已经足够了:此处的交换引用不再通过,因为右侧的引用(const int&
参数传递给了minmax
(不参考与在左侧(std::tie
创建的参考文献的tuple
(。
输出是根据需要的:
a:5,b:7
有时候,退后一步,找到另一种方式回报:
if (b < a)
std::iter_swap(&a, &b);
这很简洁,通常更有效,至少在标准杆上。也许将其包装到自己的功能中:
template <class T>
void reorder(T& a, T& b)
noexcept(noexcept(b < a, void(), std::iter_swap(&a, &b))) {
if (b < a)
std::iter_swap(&a, &b);
}
我正在使用std::iter_swap()
,因此我不必在PRE-C 2A中使用using std::swap; swap(a, b)
两步进行通用,该pre-c 2a中引入了自定义点对象,使该对象变得过时。
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 我可以重新分配/覆盖std::字符串吗
- 为什么 std::equal_to会导致动态分配?
- 使 std::vector 分配对齐内存的现代方法
- 如何增加以前由新运算符分配的 C++ std::list 数组的大小?
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- C++ 使用枚举类对象分配 std::map 值
- std::元组分配和复制/移动异常保证
- 使用 std::vector 在类中分配索引
- vector是否为std::移动的对象连续分配内存
- std::initializer_list 堆是否分配内存?
- std::p air 会破坏其动态分配的对象吗?
- 在std::线程中使用已分配的结构数据
- 无法使用"std::make_shared"分配指针
- std矢量内存分配linux与windows编译器
- 如何为包含最多N个元素的std::multiset调用最大数量分配
- 如何在 C++11 的内存池中分配 std::map 的内部RB_tree节点?
- 如何使用 std::vector 防止内存重新分配
- 使用 std::map 的递归堆栈分配如何工作?
- 我可以使用std ::分配的分配的原始数组