c++ std::ignore与结构化绑定?

lbsnaicq  于 11个月前  发布在  其他
关注(0)|答案(5)|浏览(125)

前奏曲:

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


是否有可能使用新的结构化绑定语法来做类似的事情?它将如何工作?

62lalag4

62lalag41#

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

llmtgqce

llmtgqce2#

是否有可能使用新的结构化绑定语法来做类似的事情?
不,你只需要编一个变量名,这个变量名以后不会被提到。

mbyulnm0

mbyulnm03#

我通常使用_,这是C++中的有效标识符,但看起来与Kotlin的下划线运算符相同,它丢弃了lambda参数。

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

字符串

qfe3c7zg

qfe3c7zg4#

这里有一个快速而肮脏的技巧,但它只适用于每行一个下划线。(使用C++20的source_location也可以将其扩展到列):

#define __CONCAT(x,y) x ## y
#define _CONCAT(x,y) __CONCAT(x,y)
#define _ _CONCAT(__tmp_ignore_var_, __LINE__)

int main(int argc, char* argv[])
{
    auto p = make_pair(2,"hello");
    auto [_, b] = p;
    auto [a, _] = p;
    return 0;
}

字符串

qkf9rpyu

qkf9rpyu5#

C++26将引入A nice placeholder with no name (P2169R0)。有了这个新的语言特性,人们终于可以使用_作为忽略结构化绑定表达式中变量的一种方式。有关设计的详细信息,请参阅链接文档。

相关问题