【问题标题】:structured binding with [[maybe_unused]]与 [[maybe_unused]] 的结构化绑定
【发布时间】:2017-05-15 05:06:53
【问题描述】:

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

有了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);

这里不能使用attributes有什么具体原因吗? (在标准和技术上)。 gcc 和 clang 都不接受这个。


编辑,收集支持状态:(感谢godbolt/compiler explorer)。它按预期工作(也可能更早):

  • gcc 8.0 主干(g++ 8.0.0 20171015 实验性)
  • clang 4.0.0
  • icc 18(未经测试,根据specs)
  • msvc 19.22(可能更早)(已修复,根据bug report)

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

【问题讨论】:

  • 我想可能会阻止嵌套分解可能是一个问题。
  • 嗯。好的...[g,[[possibly_unused]]] = foo()..我想得越多,我就越能把那个单一的属性放在外面:-)
  • 确实需要 gcc > 7.2 才能使属性起作用。
  • 所以 [[maybe_unused]] 阻止了警告,但是你也失去了对你实际想要使用的返回值的任何检查。

标签: c++ c++17 structured-bindings


【解决方案1】:

在结构绑定论文中:

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

他们讨论他们的推理:

3.8 是否有办法显式忽略组件?

动机是使编译器对未使用的名称发出警告。

我们认为答案应该是“还没有”。这不是出于使用动机 案例(消除编译器警告是一种动机,但它不是 用例本身),最好留到我们可以在 更一般的模式匹配建议的上下文,这应该 作为特例脱落。

与 std::tie 的对称性建议使用 类似于 std::ignore:

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

但是,这感觉很尴尬。

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

虽然这没有明确解决[[maybe_unused]],但我认为推理可能是相同的。停止编译器警告不是用例。

【讨论】:

  • 如果maybe_unused 有一个用例,那么将maybe_unused 附加到一个在结构化绑定中声明的变量就有一个用例。这只是声明变量的另一种方式。
  • 这仍然缺乏关于为什么不允许属性语法的推理。例如:for (auto&amp; [x, y [[gnu::whatever]], z] = f() ) { .. }。 gnu::whatever 可能意味着什么并不重要——属性语法对未来的扩展是开放的。不太有用的理由是 C++20 中当前可用的属性集不太可能在这种情况下使用。
  • @Ethouris 在提出这个问题时,C++17 仍未发布,因此在提供此答案时,它是否在 C++20 中得到解决并不是一个真正已知的事情。
  • 但即使在 C++20 中,问题似乎仍然没有得到解决,而且我认为推理没有改变。我目前正在使用for ([[maybe_unused]] auto&amp; [x, y, z] = f() ),它解决了警告问题,但隐藏了其他问题。使用它的情况并不少见 - 例如,如果您在地图上循环,但您对键的值不感兴趣。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2017-04-02
    • 1970-01-01
    • 2022-12-15
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多