std :: ignore与结构化绑定?


82

序幕:

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();

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


2
只需在其中输入一个任意名称即可。
n。代词

1
@nm不会以任意名称创建副本吗?
Piotr Skotnicki

1
@Piotrstd::ignore我想复制的不多。由于我们保证了复制省略,因此将初始化哑变量。使用std::tie,将std::ignore初始化分配给其的rhs处的临时文件。
j6t

1
可能会有一个auto[IGNORE]生成唯一名称的宏(例如,使用特定于编译器的COUNTERLINE)。它将足够可读,并且在实践中将类似于std::ignorefor std::tie
KABoissonneault

2
@PiotrSkotnicki不,decomp声明唯一能复制的就是被分解的东西。声明的事物是该事物的成员/元素的别名,或者是绑定到get返回内容的引用。
TC

Answers:


57

结构化绑定建议包含一个专门的部分来回答您的问题(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


6
现在为时已晚,但我要指出的是,一个使用起来很尴尬并且将来可能会被替换的功能总比完全没有能力使用该功能要好,而且这似乎不是那种这会使标准委员会希望有一个时光机,因为对std::ignore结构化绑定没有其他合理的解释。
Daniel H

9

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

不。您只需要组成一个变量名,以后将不再提及。


25
可以生成未使用的变量警告-Wunused-variable,您可以使用:[[maybe_unused]] auto [ a, b, dummy ] = std::tuple(1,"2",3f);但是这意味着它们中的任何一个都可能未被使用,您将不知道哪个。目前没有针对这种情况的好的解决方案。希望它将在c ++ 20中得到改善。从这里取:stackoverflow.com/questions/41404001/...
丝氨酸

3
“目前没有针对这种情况的好的解决方案”:并非完全正确:您可以使用(void)dummy;摆脱未使用的变量警告,而不会影响其他变量。
andreee

16
@andreee:用完一个语句只是为了消除警告不是我所说的“好的解决方案”。
尼科尔·波拉斯

“使用语句只是为了消除警告...”我们用完了语句吗?
AndyJost

1
@AndyJost:否,但是我们屏幕上的可视空间已用完。将它(特别是宝贵的垂直空间)用于消除警告无效,这是没有用的。
Nicol Bolas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.