Когда я использую лямбда-выражения для сложной инициализации переменных, как я могу обрабатывать внешние лямбда-исключения, которые выдают изнутри? - PullRequest
2 голосов
/ 04 ноября 2019

Я использую лямбда-выражения для инициализации некоторых const переменных, как описано в основных рекомендациях по c ++ здесь . Короче говоря, идиома выглядит следующим образом:

const auto a = [&]() {
    MyType a;
    // complex initialization
    return a;
}();

Проблема возникает, когда инициализация может вызвать исключение, которое может быть обработано только за пределами лямбды, например, из-за того, что оно должно вызвать преждевременный возврат функции. Я хочу иметь возможность делать что-то похожее на это

try {
    const auto a = [&]() {
        MyType a;
        // complex initialization
        return a;
    }();
} 
catch { /* doesn't matter what */ } {
    // Somehow handle it
    // then return or throw
}
// use a

, за исключением того, что я хочу, чтобы объект мог использоваться после блока try-catch, когда исключение не выдается.

Iмог бы реорганизовать функцию так, чтобы весь код, который зависит от успешной инициализации объекта, находился внутри блока try, но это ужасно масштабировалось с несколькими объектами для инициализации.

try {
    const auto a = ...;
    try {
        const auto b = ...;
        try...
        catch...
    }
    catch {...} {
        ...;
    }
catch {...} {
    ...;
}

С другой стороны, перемещая попытку-catch блок внутри лямбда ограничивает то, что я могу сделать, чтобы справиться с этим. например, это не позволяет мне мгновенно return, break или continue, насколько я могу судить. Похоже, что логическим решением было бы чередовать назначение с блоком try (например, const auto a = try [&]()...), но, похоже, это не поддерживается языком. Правильно ли я в том, что это не поддерживается, и если да, то есть ли другая известная идиома, которая привела бы к нужному мне поведению?

Примечание: я спрашиваю о ситуациях, в которых важно, чтобы переменная была const или если конструкция по умолчанию с последующим присваиванием невозможна, поэтому очевидное решение конструирования по умолчанию вне блока try и присвоения значения внутри него нежизнеспособно.

...