有没有一种很好的方法将std :: minmax(a,b)分配给std :: tie(a,b)? [英] Is there a nice way to assign std::minmax(a, b) to std::tie(a, b)?

查看:63
本文介绍了有没有一种很好的方法将std :: minmax(a,b)分配给std :: tie(a,b)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std::tie(a, b) = std::minmax(a, b);

我认为这是直观的代码.干净易懂.太糟糕了,它无法按预期工作,例如 std :: minmax 用于 const& 的模板.因此,如果在 std :: pair< const& ;, const&> 内交换值,则一个分配将覆盖另一个值:

I think this is intuitive code. Clean and understandable. Too bad it doesn't work as intended, as std::minmax templates for const&. If therefore the values are swapped inside the std::pair<const&, const&> than one assignement will overwrite the other value:

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: 5

此处的预期输出为 a:5,b:7 .

我认为这很重要,因为实现转换功能以将功能应用于某些范围需要直观的lambda的此类声明.例如:

I think this is important as implementing transform functions to apply a function onto some ranges requires such statements for intuitive lambdas. For example:

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 :: tuple std :: pair< const& ;、 const&> 上没有任何引用限定符以强制执行副本:


One solution I found was constructing an std::tuple explicitly without any reference qualifiers over the std::pair<const&, const&> to enforce a copy:

std::tie(a, b) = std::tuple<int, int>(std::minmax(a, b)); 

但是,这种< int,int> 冗余似乎相当糟糕,尤其是在具有 auto&a,自动&b 之前.

But this <int, int> redundancy seems rather awful, especially when having saidauto& a, auto& b before.

是否有一种不错的,简短的方法来执行此分配?可能这是错误的方向,只是说 if(a> = b){std :: swap(a,b);} 是这里最好的方法吗?

Is there a nice, short way to perform this assignement? Could it be that this is the wrong direction and just saying if (a >= b) { std::swap(a, b); } would be the best approach here?

推荐答案

您可以将初始化器列表用于 minmax :

You can use an initializer list for minmax:

std::tie(a, b) = std::minmax({a, b});

这将导致创建临时对象,就像使用一元加号时一样,但是具有的好处是它也可用于缺少一元加号运算符的类型.

This causes temporary objects to be created, just like when using unary plus, but has the benefit that it works with types lacking the unary plus operator too.

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);} 是这里最好的方法吗?

由于

I'd make it if(b < a) std::swap(a, b); because of the Compare1 requirement, but yes, I suspect that'll be faster and it's still very clear what you want to accomplish.

[1] 比较应用于对象的函数调用操作的返回值满足条件比较的类型,当上下文转换为bool时,如果调用的第一个参数出现在在由这种类型引起的严格的弱有序关系中排名第二,并且否则为false.

这篇关于有没有一种很好的方法将std :: minmax(a,b)分配给std :: tie(a,b)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆