加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

依赖表达式和ODR在C 14中的通用Lambda中的使用

发布时间:2020-12-13 20:46:30 所属栏目:百科 来源:网络整理
导读: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 };
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.
>其次,我删除了(注释掉了)lambda g2中的capture-default.

此代码是否符合标准? 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).
>或者,当存在capture-default时,依赖表达式隐式捕获变量的条件是否仅适用?这意味着,没有odr-use(即,没有const int& in function f()#2),无论capture-default如何,程序都将以相同的方式工作.因此,关于依赖表达式的第二个条件不会无用吗?

这是C 14标准(ISO / IEC 14882:2014),第12段(强调我的):

A lambda-expression with an associated capture-default that does not explicitly capture this or a variable with automatic storage duration (this excludes any id-expression that has been found to refer to an init-capture’s associated non-static data member),is said to implicitly capture the entity (i.e.,this or a variable) if the compound-statement:

  • odr-uses (3.2) the entity,or
  • names the entity in a potentially-evaluated expression (3.2) where the enclosing full-expression depends on a generic lambda parameter declared within the reaching scope of the lambda-expression.

注意:lambda g不捕获变量x,因为它在f(x)中没有使用odr(参见C 14标准(ISO / IEC 14882:2014),第13段)

链接:

> N3649: Generic (Polymorphic) Lambda Expressions (Revision 3)
> Using of not captured variable in lambda

Is this code Standard-compliant?

是.规则是:

If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses (3.2) this or a variable with
automatic storage duration from its reaching scope,that entity shall be captured by the lambda-expression.

lambda odr-use x?不,因为[basic.def.odr]:

A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.20) that does not invoke any non-trivial
functions and,if x is an object,ex is an element of the set of potential results of an expression e,where either the lvalue-to-rvalue conversion (4.1) is applied to e,or e is a discarded-value expression (Clause 5).

x是一个整数常量,用于应用左值到右值转换的表达式中,因此不会使用它.因为它没有使用,所以你没有抓住它并不是一个错误.

如果有一个超载的f通过引用获得它的第一个参数 – 那将是错误形成的 – 调用操作符的实例化将使用x,但它没有被捕获,使其形成不良.

您引用的部分与您修改的示例无关.它仅指“具有相关捕获默认值的lambda表达式”.但是你的lambda没有捕获默认值.捕获默认值为=或&,介绍人[]没有捕获默认值.但是,如果我们有[=]或[&],该部分将解释为什么会捕获x.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读