temporary lifetime in range-for expression

后端 未结 2 1779
死守一世寂寞
死守一世寂寞 2020-12-14 18:19

Consider a simple class A that can be used as a range:

struct A { 
    ~A() { std::cout << \"~A \"; }

    const char* begin() const {
            


        
2条回答
  •  醉梦人生
    2020-12-14 18:45

    The reason the lifetime of the temporary is not extended is how the standard defines range-based for loops in

    6.5.4 The range-based for statement [stmt.ranged]

    1 For a range-based for statement of the form

    for (for-range-declaration:expression)statement

    let range-init be equivalent to the expression surrounded by parentheses

    ( expression )

    and for a range-based for statement of the form

    for (for-range-declaration:braced-init-list)statement

    let range-init be equivalent to the braced-init-list. In each case, a range-based for statement is equivalent to

    {
       auto && __range = range-init;
       for ( auto __begin = begin-expr,
                  __end = end-expr;
             __begin != __end;
             ++__begin ) {
          for-range-declaration = *__begin;
          statement
       }
    }
    

    Note that auto && __range = range-init; would extend the lifetime of a temporary returned from range-init, but it does not extend the lifetime of nested temporaries inside of range-init.

    This is IMHO a very unfortunate definition and was even discussed as Defect Report 900. It seems to be the only part of the standard where a reference is implicitly bound to extend the lifetime of an expressions result without extending the lifetime of nested temporaries.

    The solution is to store a copy in the wrapper - which often defeats the purpose of the wrapper.

提交回复
热议问题