使用[[maybe_unused]]进行结构化绑定

structured binding with [[maybe_unused]]

本文关键字:绑定 结构化 unused maybe 使用      更新时间:2023-10-16

具有模式匹配的函数式语言(有时?)有可能忽略一些绑定值,但对于C++17结构化绑定,似乎没有办法做到这一点(std::忽略结构化绑定?)。建议是使用一个伪名称,但随后我们会收到关于未使用变量的警告。

有了clang和gcc的最新负责人,这做了预期的事情,这很好,也很有用,

[[maybe_unused]] auto x =4 ; // fine, no warning
[[maybe_unused]] auto [a,dummyb,dummyc] = std::tuple<int,int,float>(1,1,1.0f); 

但我也希望这能奏效:

auto [g,[[maybe_unused]]dummyh,[[maybe_unused]]dymmyi] =
std::tuple<int,int,float>(1,1,1.0f);

这里不能使用属性有什么具体的原因吗?(在标准中以及在技术上)。gcc和clang都不接受这一点。


编辑,收集支持状态:(感谢godbolt/编译器资源管理器)。它在中按预期工作(也可能更早):

  • gcc8.0主干(g++8.0.020171015实验)
  • 叮当4.0.0
  • icc18(根据规格,未测试)
  • msvc 19.22(可能更早)(已修复,根据错误报告)

在godbolt中试用https://gcc.godbolt.org/z/H2duYd

在结构绑定论文中:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0144r2.pdf

他们讨论他们的推理:

3.8是否应该有明确忽略组件的方法?

其动机是使编译器对未使用名称的警告静音。

我们认为答案应该是"还没有"。这不是出于使用动机case(使编译器警告静音是一种动机,但它不是用例本身),在我们可以在更通用的模式匹配建议的上下文作为一个特例而闹翻。

对称std::tie建议使用类似std::ignore:的东西

tuple<T1,T2,T3> f(); 
auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element 

然而,这感觉很尴尬。

预期语言中的模式匹配可以建议使用像_或*这样的通配符,但由于我们还没有模式匹配现在选择一个我们知道会是可共用的这是一个纯粹的扩展,可以等待考虑具有模式匹配。

尽管这并没有明确地解决[[maybe_unused]]问题,但我认为推理可能是一样的。停止编译器警告不是一个用例。

作为对CWG 2360的解决方案,标准的工作草案获得了以下措辞([dcl.attr.usered]):

  1. 属性可以应用于类、typedef名称、变量(包括结构化绑定声明)、非静态数据成员、函数、枚举或枚举器的声明。

  2. 对于标记为maybe_unused的实体,实现不应发出该实体或其结构化绑定(如果有)已使用或未使用的警告。对于未标记为maybe_unused的结构化绑定声明,除非其所有结构化绑定都未使用,否则实现不应发出此类警告。

结构化绑定声明以前没有明确提及。