依赖表达式和ODR在C 14中的通用Lambda中的使用
void f( int,const int (&)[2] = {}) { } // #1 void f( int,const int (&)[1] ) { } // #2 // void f(const int&,const int (&)[1] ) { } // #2_original void test() { const int x = 17; auto g = [](auto a) { f(x); // OK: calls #1,does not capture x }; auto g2 = [ /* = */ ](auto a) { int selector[ sizeof(a) == 1 ? 1 : 2 ]{}; f(x,selector); // OK: is a dependent expression,so captures x ??? }; } 这是C 14标准(ISO / IEC 14882:2014),第5.1.2节,第12段中的一个例子,我用2种方式对其进行了修改: >首先,函数f()的两个版本都有一个int作为第一个参数,因此变量x在任何情况下都不会使用odr. 此代码是否符合标准? clang和gcc都编译成功.但是,在原始示例中,lambda g2具有capture-default([=]),因此隐式捕获变量x,因为存在依赖表达式(并且还因为它可能在函数f()#2_original中使用odr).请注意,在标准的上述段落中,隐含地捕获变量x(odr-use OR dependent expression)有两个条件.现在,没有capture-default或odr-use: >这不应该是编译时错误,因为有一个依赖表达式而没有capture-default吗?也就是说,需要捕获变量x,但它不能(假设g2调用两种参数,即产生sizeof(a)= 1而其他sizeof(a)> 1). 这是C 14标准(ISO / IEC 14882:2014),第12段(强调我的):
注意:lambda g不捕获变量x,因为它在f(x)中没有使用odr(参见C 14标准(ISO / IEC 14882:2014),第13段) 链接: > N3649: Generic (Polymorphic) Lambda Expressions (Revision 3)
是.规则是:
lambda odr-use x?不,因为[basic.def.odr]:
x是一个整数常量,用于应用左值到右值转换的表达式中,因此不会使用它.因为它没有使用,所以你没有抓住它并不是一个错误. 如果有一个超载的f通过引用获得它的第一个参数 – 那将是错误形成的 – 调用操作符的实例化将使用x,但它没有被捕获,使其形成不良. 您引用的部分与您修改的示例无关.它仅指“具有相关捕获默认值的lambda表达式”.但是你的lambda没有捕获默认值.捕获默认值为=或&,介绍人[]没有捕获默认值.但是,如果我们有[=]或[&],该部分将解释为什么会捕获x. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |