Повторное использование переменной типа auto - PullRequest
3 голосов
/ 27 марта 2020

У меня есть специальный класс для использования в качестве возвращаемого типа методов, содержащий требуемое значение или, в случае сбоя, сообщение об ошибке, даже каскадное из более ранних ошибок. Он работает, как и ожидалось.

Поскольку возвращаемый тип отличается сложностью, мне нравится использовать ключевое слово auto. Но при использовании большого количества методов мне приходится создавать новые возвращаемые переменные.

Типичная часть кода выглядит следующим образом:

auto ret1 = methodA();
if(ret1.isValid()...

auto ret2 = methodB();
if(ret2.isValid()...

Мне не нравится всегда создавать новую переменную. Но мне нравится элегантный способ обработки ошибок. Использование более возвращаемого типа дампа, такого как код ошибки в целочисленном коде, решит проблему, но тогда я не получу никакой выгоды от типа возвращаемого значения обработки ошибок.

Есть ли хитрость для повторного использования первой возвращаемой переменной ret1?

Ответы [ 4 ]

4 голосов
/ 27 марта 2020

Вам потребуется создать новые области, чтобы повторно использовать имя переменной для другой переменной, например:

{
    auto ret = methodA();
    if (ret.isValid()) ...
}
{
    auto ret = methodB();
    if (ret.isValid()) ...
}

Вы также можете воспользоваться областью, созданной if, поместив оператор init внутри:

if (auto ret = methodA(); ret.isValid()) ...

if (auto ret = methodB(); ret.isValid()) ...
3 голосов
/ 27 марта 2020

auto не является типом.

Это ключевое слово, которое говорит: «поместите здесь тип для меня, вычтя его из начального значения». Это происходит во время компиляции, один раз.

Вы не можете повторно использовать ret1 для хранения объектов другого типа, используете ли вы auto или нет.

Это не должно проблема. Если вы беспокоитесь о «нехватке имен» или «наличии многих похожих имен», ваши имена недостаточно описательны и / или ваши области недостаточно точны.

2 голосов
/ 27 марта 2020

auto является не типом. В auto foo = bar(); компилятор просто выясняет, какой тип bar() на самом деле возвращает и подставляет его. Так что если bar() возвращает int, то это тип foo, если он возвращает bool, то , что - это тип foo. И как только тип, который auto должен быть заменен (первый раз), определен, он может никогда не изменяться. auto не означает «тип переменной», это просто означает «эй, компилятор, мне лень выяснять, какой тип поместить здесь, пожалуйста, сделайте это для меня», но разницы нет, что-так * когда-нибудь по сравнению с тем, что вы сами пишете последний тип. Таким образом, вы можете повторно использовать переменную, если то, что вы присваиваете ей во второй раз, имеет тот же тип, что и первый раз, иначе - нет.

1 голос
/ 27 марта 2020

Мне не нравится всегда создавать новую переменную.

Гораздо лучше создать переменную const:

const auto ret1 = methodA();
if(ret1.isValid()...

const auto ret2 = methodB();
if(ret2.isValid()...

В этом случае вам нужно сделать const всех методов, таких как isValid, но это еще лучше: «is» не должен иметь побочных эффектов и изменять состояние.

Следующий шаг - вообще удалить временную переменную:

if(methodA().isValid()) {
    ...
}

if(methodB().isValid()) {
    ...
}

Альтернативой является упаковка каждого вызова функции в блок:

{
    const auto ret = methodA();
    if(ret.isValid()...
}

{
    const auto ret = methodB();
    if(ret.isValid()...
}

Это позволяет вам повторно использовать имя переменной const.

Каждый блок становится кандидат на извлечение в отдельную функцию (см. «Дядя Боб» в «Чистом коде»).

...