Lambda capture during initialization should be a mistake

What I'm trying to do is exceptions when creating an object that may be invalid. This would be ideal for use std::optional, but I do not think that omission std::optionalchanges the error that I see: the object is captured and used before it is initialized. I do not think that this should be captured first of all, because we have not reached the point of sequence, as far as I know (is lambda initialization considered a point of sequence?). Moreover, an error is an IMO, an easily perceptible human error (and even comes across ... depending on the circumstances).

How (more importantly, why) is a lambda capable of capturing and using an uninitialized one foo?

https://godbolt.org/g/IwcHrV

#include <string>
using namespace std;

void foo() {
  string foo = [&]()->string{
    // using foo before it been initialized == undefined behavior
    auto guessed_foo = to_string(1234);
    if ( begin(foo) == end(foo) ) {
      return guessed_foo;
    }
    return {};
  }();
}

The compiler exited with result code 0

But ... replacing the declaration string foowith one auto foodoes indeed cause an error similar to what I would like to see.

https://godbolt.org/g/GfE4WH

#include <string>
using namespace std;

void foo() {
  auto foo = [&]()->string{
    auto guessed_foo = to_string(1234);
    if ( begin(foo) == end(foo) ) {
      return guessed_foo;
    }
    return {};
  }();
}

error: the variable 'foo' declared with type 'auto' cannot appear in its own initializer

Note that I found this using GCC 6.2 on Ubuntu 16.04 LTS. Configuration in Godbolt uses clang 3.9.1. Both are configured for C ++ 14.

So my questions are:

  • Why is lambda capture to initialize a human variable capable of capturing and using a variable (not yet initialized)?
  • Why autois it (in my opinion, correct) that it is caught and mistaken?
  • , ? , ... - , ?
  • auto?
+4
1

[dcl.spec.auto]/10:

- .

foo foo , foo, .


, - , . "int = i;" ?. std::function:

std::function<void(int)> foo = [&foo](int i){ return foo(i - 1); };
+2

Source: https://habr.com/ru/post/1673332/


All Articles