【发布时间】:2020-12-03 16:28:04
【问题描述】:
考虑以下代码:
#include<functional>
#include<iostream>
#include<map>
const std::map<int, std::string> numberToStr{{1, "one"}, {2,"two"}};
int main() {
auto it = numberToStr.find(2);
if (it ==numberToStr.end()){
return 1;
}
const auto&[_, str] = *it;
std::cout << str;
}
我有什么办法可以将可能被取消引用的it 解包为 2 个选项(_ 和 str),这样我就可以写了:
const auto&[_, str] = // some magic;
// _ is std::optional<int>, str is std::optional<str>
if (!str){
return 1;
}
std::cout << *str;
}
我认为不是,因为结构化绑定是语言级别的东西,而 std::optional 是一个库功能,而且 afaik 没有办法自定义交互。
注意:我想我可以实现自己的映射,该映射返回知道它们是否指向 .end() 的迭代器,并“破解”自定义点以基于此执行可选逻辑,当我要求一般用例时不要控制容器。
【问题讨论】:
-
我不关注。如果你不控制容器,你就会得到你所得到的。你期待什么样的魔法?如果对
.find的调用被包装在一个返回一对可选项的函数中,那可以吗? -
@cigien 我碰壁了,如果我知道解决方案的一些方向,我会提供它,但我只知道我想要什么(解包可能是 .find 返回的一对可选-s) ,内森的回答是,我认为如果没有 WG21 将这样的东西烘焙成语言,我能得到最好的结果......
-
当然,没关系。你的措辞让我有点失望,仅此而已。顺便说一句,这无论如何都不是语言问题,而是库问题,因为它处理
map::find返回的内容。所以这将取决于 LWG,我认为。并不是说签名会被改变来做你想做的事。 -
这个问题对我来说没有意义。代码已经在检查
find()的结果以确保返回的iterator是有效的,在这种情况下,该地图元素的string也是有效的并且不能是可选的。当您可以直接从迭代器访问string时,根本不需要使用结构化绑定,例如:if (it == numberToStr.end()){ return 1; } std::cout << it->second; -
@cigien:没问题:有website 告诉你这些事情,但你必须知道它的存在!
标签: c++ c++17 c++20 structured-bindings