C++ std::忽略结构化绑定?

C++ std::忽略结构化绑定?,c++,language-lawyer,c++17,C++,Language Lawyer,C++17,序曲: std::tuple<int, int, int> f(); std::tuple<int, int, float, int> g(); 差不多 auto [a, b, c] = f(); 但是,std::tie也允许指定std::ignore忽略某些组件,例如: std::tie(a, b, std::ignore, c) = g(); 是否可以使用新的结构化绑定语法执行类似的操作?它将如何工作 是否可以使用新的结构化绑定语法执行类似的操作 不,您只需要编

序曲:

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

auto [a, b, c] = f();
但是,
std::tie
也允许指定
std::ignore
忽略某些组件,例如:

std::tie(a, b, std::ignore, c) = g();
是否可以使用新的结构化绑定语法执行类似的操作?它将如何工作

是否可以使用新的结构化绑定语法执行类似的操作

不,您只需要编一个变量名,以后不会再提到

是否可以使用新的结构化绑定语法执行类似的操作


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

结构化绑定方案包含一个专用部分,用于回答您的问题():

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

这样做的动机是消除编译器对未使用名称的警告。 我们认为答案应该是“还没有”。这不是出于用例的动机(沉默编译器警告是一种动机,但它本身不是一个用例),最好留到我们可以在更一般的模式匹配建议的上下文中重新讨论这一点,在这种情况下,这应该作为一个特例

std::tie的对称性建议使用
std::ignore

tuple<T1,T2,T3> f();

auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element
tuple f();
auto[x,std::ignore,z]=f();//未提议:忽略第二个要素
然而,这感觉很尴尬

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

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

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


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

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

这样做的动机是消除编译器对未使用名称的警告。 我们认为答案应该是“还没有”。这不是出于用例的动机(沉默编译器警告是一种动机,但它本身不是一个用例),最好留到我们可以在更一般的模式匹配建议的上下文中重新讨论这一点,在这种情况下,这应该作为一个特例

std::tie的对称性建议使用
std::ignore

tuple<T1,T2,T3> f();

auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element
tuple f();
auto[x,std::ignore,z]=f();//未提议:忽略第二个要素
然而,这感觉很尴尬

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

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

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


<>我通常使用< /C> >这是C++中的一个有效标识符,但看起来与Kotlin的下划线操作符一样,它丢弃lambda参数。 你最终会得到一个像这样的好代码

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

<>我通常使用< /C> >这是C++中的一个有效标识符,但看起来与Kotlin的下划线操作符一样,它丢弃lambda参数。 你最终会得到一个像这样的好代码

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

只要在那里输入一个任意名称。@n.m.任意名称不会创建副本吗?@Piotr我想不会比使用
std::ignore
创建更多副本。因为我们保证了拷贝省略,所以虚拟变量被初始化;使用
std::tie
,位于
std::ignore
赋值rhs处的临时变量将被初始化。可以使用生成唯一名称的宏
auto[ignore]
(例如:使用编译器特定的计数器或行)。它的可读性足够好,在实践中的功能类似于
std::ignore
对于
std::tie
@PiotrSkotnicki不,decomp声明所做的唯一副本就是正在分解的东西。声明的对象要么是该对象的成员/元素的别名,要么是绑定到
get
返回的内容的引用。只需在那里输入任意名称。@n.m.任意名称不会创建副本吗?@Piotr我想,没有比
std::ignore
更多的副本了。因为我们保证了拷贝省略,所以虚拟变量被初始化;使用
std::tie
,位于
std::ignore
赋值rhs处的临时变量将被初始化。可以使用生成唯一名称的宏
auto[ignore]
(例如:使用编译器特定的计数器或行)。它的可读性足够好,在实践中的功能类似于
std::ignore
对于
std::tie
@PiotrSkotnicki不,decomp声明所做的唯一副本就是正在分解的东西。声明的内容要么是该内容的成员/元素的别名,要么是绑定到
get
返回内容的引用。这将生成未使用的变量warning
-Wunused variable
,您可以使用:
[[maybe\u unused]]auto[a,b,dummy]=std::tuple(1,“2”,3f)但这意味着其中任何一个都可能未使用,您将不知道是哪一个。对于这个问题没有好的解决办法