如何解决使用Lambda完美配对对秒
为什么此代码段无法编译?
flask.redirect
使用gcc的错误是:
#include <iostream>
#include <vector>
#include <ranges>
#include <unordered_map>
namespace vw = std::ranges::views;
int main()
{
auto get_second = [](auto&& pair) constexpr noexcept -> decltype(auto)
{ return std::forward<decltype(pair)>(pair).second; };
std::unordered_map<unsigned,std::pair<double,char> > m = {{5,{0.,'a'}}};
for (auto& [d,c] : m | vw::transform(get_second))
c = 'b';
for (auto const& pair : m)
std::printf("(%u,(%.3f,%c))\n",pair.first,pair.second.first,pair.second.second);
}
main.cpp: In function 'int main()':
main.cpp:16:53: error: cannot bind non-const lvalue reference of type 'std::pair<double,char>&' to an rvalue of type 'std::__success_type<std::pair<double,char> >::type' {aka 'std::pair<double,char>'}
16 | for (auto& [d,c] : m | vw::transform(get_second))
| ^
不能解决-> decltype(auto)
吗?如果我将std::pair<double,char>&
替换为-> decltype(auto)
,它将按预期工作。
解决方法
-> decltype(auto)
不能评估为std::pair<double,char>&
吗?
不。这是一个简单得多的示例:
struct X {
int i;
};
X x{42};
decltype(auto) i = x.i;
i
是int
还是int&
?这是int
。 decltype(auto)
通过将decltype(...)
应用于右侧来派生其类型。 decltype(x.i)
只是为您提供成员的类型,即int
。
要获取int&
,您必须执行以下操作:
decltype(auto) i = (x.i);
因为现在,我们将类型设为decltype((x.i))
,它产生int&
。
decltype
有一个special rule用于非括号访问-因此添加括号可以避开它。这就是decltype(x.i)
和decltype((x.i))
可以不同的原因。一旦我们回避了那个,在类型为decltype
的左值上的T
就会产生类型为T&
的类型。 x.i
是类型int
的左值,因此我们得到int&
。
请注意,我说的可以有所不同,而必须则不同,如果成员i
的类型为int&
,则两个{{1 }}和decltype(x.i)
将是decltype((x.i))
。
回到原始示例,您可以选择对返回的表达式加括号(并删除不必要的int&
):
constexpr
或者只是知道因为我们正在进行类成员访问,所以它永远不会成为prvalue,因此我们可以简化为使用auto get_second = [](auto&& pair) noexcept -> decltype(auto)
{ return (FWD(pair).second); };
(不需要其他括号):
auto&&
标准库本身也提供了以下简称:
auto get_second = [](auto&& pair) noexcept -> auto&&
{ return FWD(pair).second; };
您可以改写:
for (auto& [d,c] : m | vw::transform(get_second))
(如果需要其他元素,也可以使用for (auto& [d,c] : m | vw::values)
。
最后,视图名称空间的简称通常是elements<1>
(而不是rv
)。或只使用vw
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。