std :: ignore with structured bindings?

时间:2016-11-18 09:08:17

标签: c++ language-lawyer c++17

前奏:

std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();

C ++ 1z将引入结构化绑定的语法,这样可以编写而不是

int a, b, c;
std::tie(a, b, c) = f();

类似

auto [a, b, c] = f();

但是,std::tie也允许指定std::ignore来忽略某些组件,例如:

std::tie(a, b, std::ignore, c) = g();

使用新的结构化绑定语法是否可以做类似的事情?它会如何运作?

3 个答案:

答案 0 :(得分:33)

结构化绑定提案包含一个专门的部分来回答您的问题(P0144R2):

  

3.8是否有办法明确忽略组件?

     

动机是让编译器警告有关未使用的名称。   我们认为答案应该是“还没有。”这不是用例的动机(沉默编译器警告是一种动机,但它本身不是一个用例),最好留待我们在上下文中重新考虑这一点。一个更一般的模式匹配提案,这应该作为一个特例。

     

std::tie对称会建议使用类似std::ignore

的内容
tuple<T1,T2,T3> f();

auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element
     

然而,这感觉很尴尬。

     

预测语言中的模式匹配可能会建议使用_*这样的通配符,但由于我们还没有模式匹配,因此选择我们知道兼容的语法为时过早。这是一个纯粹的扩展,可以等待模式匹配。

但请注意,标准的工作草案目前正由相关国家机构(NB)修订,并且有一条NB评论要求此功能(P0488R0,US100):

  

分解声明应提供放弃某些返回值的语法,就像std::tie使用std::ignore一样。

答案 1 :(得分:3)

  

使用新的结构化绑定语法是否可以做类似的事情?

没有。您只需要编写一个后来不会被提及的变量名称。

答案 2 :(得分:2)

我通常使用 _,它是 C++ 中的有效标识符,但看起来与 Kotlin 的下划线运算符相同,它丢弃了 lambda 参数。 你最终会得到一个像这样的漂亮代码

map([&](auto it) {
    auto [_, deviceServiceXAddr] = it;
    return deviceServiceXAddr;
});