使用[[maybe_unused]]进行结构化绑定
structured binding with [[maybe_unused]]
具有模式匹配的函数式语言(有时?)有可能忽略一些绑定值,但对于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]):
属性可以应用于类、typedef名称、变量(包括结构化绑定声明)、非静态数据成员、函数、枚举或枚举器的声明。
对于标记为
maybe_unused
的实体,实现不应发出该实体或其结构化绑定(如果有)已使用或未使用的警告。对于未标记为maybe_unused
的结构化绑定声明,除非其所有结构化绑定都未使用,否则实现不应发出此类警告。
结构化绑定声明以前没有明确提及。
- 在基于范围的for循环中使用结构化绑定声明
- 使用结构化绑定'Reflection'
- 为什么结构化绑定不使用"auto&"返回对结构成员的引用,而是返回成员本身
- 为什么 boost::comb 对结构化绑定的支持缺少结构化绑定机制对 boost::tuples::cons 的适应?
- 结构化绑定初始值设定项表单 { 赋值表达式 } 对于 clang 上的数组类型失败
- 在 C++14 中手动实现结构化绑定
- 为什么结构化绑定不支持可变数组?
- 在只读(即 const)访问器上执行结构化绑定的最佳实践是什么?
- 带有 std::minmax 和 rvalues 的结构化绑定
- 在无序映射的结构化绑定中推导类型
- 为什么基于范围的 for 循环中的结构化绑定只是一个副本而不是引用?
- 您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)
- 结构化绑定:遍历元组的双端面
- 结构化绑定是否适用于 std::vector?
- 结构化绑定,无需复制即可获取子向量的连续元素
- 成员变量的结构化绑定
- 结构化绑定语法是否可以在多态 lambda 中使用
- 如何 std::绑定模板化函数
- boost::绑定模板化的函子
- 绑定模板化的标准库函数