gpt4 book ai didi

c++ - 具有 std::minmax 和右值的结构化绑定(bind)

转载 作者:IT老高 更新时间:2023-10-28 22:14:04 24 4
gpt4 key购买 nike

在将 std::minmax 与结构化绑定(bind)一起使用时,我遇到了一个相当微妙的错误。似乎传递的右值并不总是像预期的那样被复制。最初我在自定义容器上使用 T operator[]() const,但它似乎与文字整数相同。

#include <algorithm>
#include <cstdio>
#include <tuple>

int main()
{
auto [amin, amax] = std::minmax(3, 6);
printf("%d,%d\n", amin, amax); // undefined,undefined

int bmin, bmax;
std::tie(bmin, bmax) = std::minmax(3, 6);
printf("%d,%d\n", bmin, bmax); // 3,6
}

使用带有 -O1 -Wuninitialized 的 GCC 8.1.1 将导致 0,0 被打印为第一行并且:

warning: ‘<anonymous>’ is used uninitialized in this function [-Wuninitialized]

-O2 的 Clang 6.0.1 也会给出错误的第一个结果而没有警告。

-O0 处,GCC 给出了正确的结果并且没有警告。对于 clang,结果在 -O1-O0 处似乎是正确的。

第一行和第二行不应该是等价的,因为右值仍然可以被复制吗?

另外,为什么这取决于优化级别?特别令我惊讶的是 GCC 没有发出警告。

最佳答案

auto [amin, amax] 中的重要注意事项是auto , auto&等等被应用到组成的对象 e用返回值 std::minmax 初始化,这是一对。本质上是这样的:

auto e = std::minmax(3, 6);

auto&& amin = std::get<0>(e);
auto&& amax = std::get<1>(e);

amin 的实际类型和 amax是指任何 std::get<0> 的引用和 std::get<1>返回该对对象。他们自己返回对早已不复存在的对象的引用!

当您使用 std::tie 时,您正在对现有对象进行分配(通过引用传递)。右值不需要比它们产生的赋值表达式的生命周期更长。


作为一种解决方法,您可以使用类似这样的功能(不是生产质量):

template<typename T1, typename T2>
auto as_value(std::pair<T1, T2> in) {
using U1 = std::decay_t<T1>;
using U2 = std::decay_t<T2>;
return std::pair<U1, U2>(in);
}

它确保对包含值类型。像这样使用时:

auto [amin, amax] = as_value(std::minmax(3, 6));

我们现在得到一个拷贝,结构化绑定(bind)引用这些拷贝。

关于c++ - 具有 std::minmax 和右值的结构化绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51503114/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com