Сколько это слишком много с ключевым словом auto C ++ 11? - PullRequest
205 голосов
/ 22 июня 2011

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

auto foo = std::make_shared<Foo>();

И более скептически для:

auto foo = bla(); // where bla() return a shared_ptr<Foo>

Я не видел много дискуссий на эту тему.Кажется, что auto может быть чрезмерно использовано, поскольку тип часто является формой проверки документации и проверки работоспособности.Где вы проводите черту при использовании auto и каковы рекомендуемые варианты использования этой новой функции?

Чтобы уточнить: я не спрашиваю философского мнения;Я прошу предполагаемое использование этого ключевого слова стандартным комитетом, возможно, с комментариями о том, как это предполагаемое использование реализуется на практике.

Примечание: этот вопрос был перенесен в SE.Programmersзатем вернитесь к переполнению стека.Обсуждение этого вопроса можно найти в этом мета-вопросе .

Ответы [ 14 ]

1 голос
/ 22 июня 2011

auto ключевое слово может использоваться только для локальной переменной, но не для аргументов или членов класса / структуры. Таким образом, это безопасно и целесообразно использовать их где угодно. Я часто их использую. Тип выводится во время компиляции, отладчик показывает тип во время отладки, sizeof сообщает об этом правильно, decltype выдаст правильный тип - никакого вреда нет. Я не считаю auto чрезмерным, никогда!

1 голос
/ 22 июня 2011

Используйте auto там, где имеет смысл выводить тип.Если у вас есть что-то, что, как вы знаете, является целым числом, или вы знаете, что это строка, просто используйте int / std :: string и т. Д. Я бы не стал беспокоиться о «чрезмерном использовании» языковой функции, если она не доходит до смешногоили запутывает код.

Это мое мнение в любом случае.

0 голосов
/ 27 марта 2017

TL; DR: см. Практическое правило внизу.

В принятом ответе предлагается следующее правило:

Используйте auto всякий раз, когда трудно сказать, как написать тип с первого взгляда, но тип правой части выражения очевиден.

Но я бы сказал, что этослишком ограничительныйИногда меня не интересуют типы, так как утверждение достаточно информативно, и я не удосужился потратить время на выяснение типа.Что я имею в виду под этим?Рассмотрим пример, который всплыл в некоторых ответах:

auto x = f();

Что делает это примером неправильного использования auto?Это мое невежество относительно типа возврата f()?Ну, это действительно может помочь, если бы я знал это, но - это не моя главная забота.Проблема в том, что x и f() довольно бессмысленны.Если вместо этого у нас было:

auto nugget = mine_gold();

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

Поэтому мой ответ таков: используйте auto всякий раз, когда компиляторпозволяет, если:

  • Вы чувствуете, что имя переменной вместе с выражением инициализации / присваивания не предоставляют достаточно информации о том, что делает оператор.
  • Вы чувствуете имя переменной вместес помощью выражения инициализации / присваивания предоставляет «вводящую в заблуждение» информацию о том, каким должен быть тип - то есть, если бы вам пришлось угадывать, что приходит вместо auto, вы могли бы сделать предположение - и это было бы неправильно, и это ложное предположениепозже в коде будут последствия.
  • Вы хотите использовать другой тип (например, ссылку).

А также:

  • Предпочитаете даватьосмысленное имя (которое не содержит имени типа, конечно) перед заменой auto на конкретный тип.
0 голосов
/ 22 июня 2011

Один из моих горьких опытов с auto это использование его с лямбда-выражениями :

auto i = []() { return 0; };
cout<<"i = "<<i<<endl; // output: 1 !!!

На самом деле, здесь i разрешено указателем на функцию int(*)().Это просто cout, но только представьте, какие плохие ошибки компиляции / выполнения могут возникнуть при использовании с template.

Вам следует избегать auto с такимивыражения и поставить правильный return тип (или управляемый decltype())

Правильное использование для приведенного выше примера будет,

auto i = []() { return 0; }(); // and now i contains the result of calling the lambda  
...