Не удалось найти правильное использование автоматического спецификатора в c ++ [duplicate]

Вы не должны использовать одно и то же имя для свойства модели и свойство ViewBag (и в идеале вы не должны использовать ViewBag вообще, а скорее модель представления с свойством IEnumerable).

При использовании @Html.DropDownListFor(m => m.CustomerId, ....) первая опция "Please Select" всегда будет выбрана, даже если значение свойства модели было установлено и соответствует одному из параметров. Причина в том, что метод сначала генерирует новый IEnumerable на основе того, который вы поставили, чтобы установить значение свойства Selected. Чтобы установить свойство Selected, он считывает значение CustomerID из ViewData, а первым, который он находит, является "IEnumerable" (а не значение свойства модели) и не может соответствовать этой строке с любым из ваши параметры, поэтому выбран первый параметр (потому что что-то должно быть).

При использовании @Html.DropDownList("CustomerId", ....) атрибуты data-val-* не будут созданы, и вы не получите никакой проверки на стороне клиента

См. этот DotNetFiddle , показывающий сравнение возможных вариантов использования. Только с использованием разных имен для свойства модели и свойства ViewBag все будет работать правильно.

151
задан deepmax 31 January 2014 в 20:19
поделиться

4 ответа

Если вы не хотите изменять элементы, а также хотите, чтобы избегали создания копий, тогда auto const & является правильным выбором:

for (auto const &x : vec)

Тот, кто предлагает вы используете auto & неправильно. Игнорируйте их.

Вот recap:

  • Выберите auto x, когда вы хотите работать с копиями.
  • Выберите auto &x, когда захотите для работы с оригинальными элементами и может изменять их.
  • Выберите auto const &x, когда вы хотите работать с оригинальными элементами и не будете их изменять.
274
ответ дан Nawaz 22 August 2018 в 16:29
поделиться
  • 1
    Спасибо за отличный ответ. Я думаю, также следует отметить, что const auto &x эквивалентен вашему третьему выбору. – smg 16 April 2015 в 15:11
  • 2
    @mloskot: Это эквивалентно. (и что вы подразумеваете под ", но это тот же синтаксис & quot; ? Синтаксис, по-видимому, отличается.) – Nawaz 12 May 2015 в 13:25
  • 3
    Отсутствует: auto&&, когда вы не хотите делать ненужную копию, и вам все равно, измените ее или нет, и вы хотите просто работать. – Yakk - Adam Nevraumont 13 May 2015 в 13:34
  • 4
    Имеет ли ссылочное различие применительно к копиям, если вы просто работаете с такими фундаментальными типами, как int / double? – user 30 January 2016 в 23:45
  • 5
    @racarate: я не могу комментировать скорость в целом , и я думаю, никто не сможет, не профилируя ее в первую очередь. Честно говоря, я не буду основывать свой выбор на скорости, а скорее на ясности кода. Если я хочу неизменность, я бы наверняка использовал const. Однако, будет ли это auto const & или auto const иметь мало различий. Я бы выбрал auto const &, чтобы быть более последовательным. – Nawaz 1 February 2016 в 07:53

Когда нам не нужно менять элементы vec, в примерах предлагается использовать первую версию.

Затем они дают неправильное предложение.

Почему они не предлагают то, что ссылается на const

. Потому что они дают неправильное предложение :-) То, что вы упоминаете, является правильным. Если вы хотите наблюдать только за объектом, нет необходимости создавать копию, и нет необходимости иметь ссылку на него const.

EDIT:

Я вижу ссылки, на которые вы ссылаетесь, предоставляют примеры итерации по диапазону значений int или некоторого другого фундаментального типа данных. В этом случае, поскольку копирование int не дорого, создание копии в основном эквивалентно (если не более эффективному), имеющему наблюдение const &.

Это, однако, не так в общем, для пользовательских типов. UDT могут быть дорогими для копирования, и если у вас нет причин для создания копии (например, для изменения извлеченного объекта без изменения исходного), тогда предпочтительно использовать const &.

3
ответ дан Andy Prowl 22 August 2018 в 16:29
поделиться
  • 1
    @MM .: Не могли бы вы упомянуть, что это за ссылки? – Andy Prowl 2 March 2013 в 17:34
  • 2
    Я связал их по номерам в моем вопросе, (1) (2) ... – deepmax 2 March 2013 в 17:36
  • 3
    @MM .: Я не вижу вашего ответа ... – Andy Prowl 2 March 2013 в 17:40
  • 4
    @MM .: ОК, это потому, что это фундаментальные типы, такие как int, и копирование значения не дорого. В принципе, он достигает того же эффекта, что и const &. – Andy Prowl 2 March 2013 в 17:44

Я собираюсь быть противоположным здесь и сказать, что нет необходимости в auto const & в диапазоне, основанном на цикле. Скажите мне, считаете ли вы, что следующая функция глупа (не в своей цели, а в том, как она написана):

long long SafePop(std::vector<uint32_t>& v)
{
    auto const& cv = v;
    long long n = -1;
    if (!cv.empty())
    {
        n = cv.back();
        v.pop_back();
    }
    return n;
}

Здесь автор создал ссылку на константу v для использования для всех операций, которые не изменяют v. Это, на мой взгляд, глупо, и тот же аргумент может быть сделан для использования auto const & в качестве переменной в диапазоне, основанном на цикле, а не только на auto &.

0
ответ дан Benjamin Lindley 22 August 2018 в 16:29
поделиться
  • 1
    @BenjaminLindley: Итак, я могу предположить, что вы также возражаете против const_iterator в цикле for? Как вы гарантируете, что вы не измените исходные элементы из контейнера, когда будете перебирать его? – Nawaz 2 March 2013 в 18:42
  • 2
    @BenjaminLindley: Почему ваш код не компилируется без const_iterator? Позвольте мне угадать, контейнер, который вы итератор, const. Но почему это const для начала? Где-то вы используете const для обеспечения чего? – Nawaz 2 March 2013 в 18:54
  • 3
    Преимущество создания объектов const аналогично преимуществам использования private / protected в классах. Это позволяет избежать дальнейших ошибок. – deepmax 2 March 2013 в 19:46
  • 4
    @BenjaminLindley: О, я забыл об этом. Тогда в этом случае реализация также глупа. Но если эта функция не изменила v, реализация будет отличной ИМО. И если цикл никогда не изменяет объекты, с которыми он итерации проходит, мне кажется, что у меня есть ссылка на const. Я вижу вашу точку зрения. Моя состоит в том, что цикл представляет собой блок кода, очень похожий на функцию, и внутри этого блока нет инструкции, которая должна изменить значение. Поэтому вы можете & quot; tag & quot; весь блок как const, как вы бы сделали с функцией const-члена. – Andy Prowl 2 March 2013 в 23:42
  • 5
    Итак, вы думаете, что const & для диапазона основано глупо, потому что вы написали нерелевантный воображаемый пример воображаемого программиста, который сделал что-то глупо с cv -qualification? ...Хорошо, тогда – underscore_d 26 February 2016 в 16:02

Если у вас есть std::vector<int> или std::vector<double>, то лучше использовать auto (со значением copy) вместо const auto&, так как копирование int или double дешево:

for (auto x : vec)
    ....

Но если у вас есть std::vector<MyClass>, где MyClass имеет некоторую нетривиальную семантику копирования (например, std::string, некоторый сложный пользовательский класс и т. д.), то я бы предложил использовать const auto&, чтобы избежать глубоких копий:

for (const auto & x : vec)
    ....
20
ответ дан Mr.C64 22 August 2018 в 16:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: