Как вложить EL внутри другого EL? [Дубликат]

Большинство ответов здесь не могут объяснить, какова фактическая проблема с разрезанием. Они объясняют только доброкачественные случаи нарезки, а не предательские. Предположим, как и другие ответы, что вы имеете дело с двумя классами A и B, где B получает (публично) из A.

В этой ситуации C ++ позволяет вам передать экземпляр оператора B в A, а также в конструктор копирования. Это работает, потому что экземпляр B может быть преобразован в const A&, а именно, какие операторы присваивания и конструкторы-копии ожидают, что их аргументы будут.

Доброкачественный случай

B b;
A a = b;

Ничего плохого в этом нет - вы попросили экземпляр A, который является копией B, и это именно то, что вы получаете. Конечно, a не будет содержать некоторых членов b, но как это сделать? В конце концов, это A, а не B, поэтому даже не слышал об этих членах, не говоря уже о возможности их хранения.

вероломный случай

B b1;
B b2;
A& a_ref = b2;
a_ref = b1;
//b2 now contains a mixture of b1 and b2!

Вы можете подумать, что b2 будет копией b1 впоследствии. Но, увы, это не так! Если вы проверите его, вы обнаружите, что b2 - это франкенштейновское существо, сделанное из некоторых кусков b1 (куски, которые B наследует от A), и некоторые фрагменты b2 (куски что только B содержит). Ой!

Что случилось? Ну, C ++ по умолчанию не обрабатывает операторы присваивания как virtual. Таким образом, строка a_ref = b1 вызовет оператор присваивания A, а не номер B. Это связано с тем, что для не виртуальных функций объявленный тип (который является A&) определяет, какая функция вызывается, в отличие от фактического типа (который был бы B, поскольку a_ref ссылается на экземпляр B ). Теперь оператор присваивания A явно знает только о членах, объявленных в A, поэтому он будет копировать только те, оставляя члены, добавленные в B без изменений.

Решение

Присвоение только части объекта обычно имеет мало смысла, но, к сожалению, C ++ не предусматривает встроенного способа запретить это. Вы можете, однако, бросить свои собственные. Первый шаг - сделать оператор присваивания виртуальным . Это гарантирует, что он всегда является оператором присваивания фактического типа, который вызывается, а не объявленным типом. Второй шаг - использовать dynamic_cast, чтобы убедиться, что назначенный объект имеет совместимый тип. Третий шаг - выполнить фактическое присвоение в члене (protected!) assign(), так как B assign(), вероятно, захочет использовать A 's assign() для копирования A членов .

class A {
public:
  virtual A& operator= (const A& a) {
    assign(a);
    return *this;
  }

protected:
  void assign(const A& a) {
    // copy members of A from a to this
  }
};

class B : public A {
public:
  virtual B& operator= (const A& a) {
    if (const B* b = dynamic_cast<const B*>(&a))
      assign(*b);
    else
      throw bad_assignment();
    return *this;
  }

protected:
  void assign(const B& b) {
    A::assign(b); // Let A's assign() copy members of A from b to this
    // copy members of B from b to this
  }
};

Обратите внимание, что для чистого удобства B operator= ковариантно переопределяет возвращаемый тип, поскольку он знает, что он возвращает экземпляр B.

40
задан newbie 12 September 2013 в 09:03
поделиться

3 ответа

, если все, что вы пытаетесь сделать, это получить значение одной записи на карте, нет необходимости цитировать любую коллекцию вообще. упростив ответ gautum, вы можете получить значение именованной записи карты следующим образом:

<c:out value="${map['key']}"/>

, где «map» - это коллекция, а «ключ» - это строковый ключ, для которого вы пытаетесь извлеките значение.

81
ответ дан jason 22 August 2018 в 06:30
поделиться
  • 1
    Это должен быть принятый ответ, но обратите внимание, что отсутствуют кавычки для значения <c:out value="${map['key']}"/> – Gonzalo 4 December 2014 в 09:45
  • 2
    Спасибо @ Gonzalo-обновленный ответ w / quotes. – jason 19 March 2015 в 15:29
  • 3
    Это то, что моя карта выглядит как {key1 = 23, key2 = 1, key3 = 0}. Я получаю эту ошибку при использовании приведенного выше кода: javax.el.PropertyNotFoundException: свойство 'key1' не найдено по типу java.util.HashMap $ Node – MR AND 26 June 2017 в 17:59

вы могли бы попробовать ниже кода

<c:forEach var="hash" items="${map['key']}">
        <option><c:out value="${hash}"/></option>
  </c:forEach>
5
ответ дан Gautam 22 August 2018 в 06:30
поделиться

У меня возникла проблема с решениями, упомянутыми выше, поскольку указание строкового ключа даст мне javax.el.PropertyNotFoundException. Код, показанный ниже, работал для меня. В этом я использовал состояние для подсчета индекса для каждого цикла и отображал значение индекса, которое меня интересует

<c:forEach items="${requestScope.key}"  var="map" varStatus="status" >
    <c:if test="${status.index eq 1}">
        <option><c:out value=${map.value}/></option>
    </c:if>
</c:forEach>    
0
ответ дан MR AND 22 August 2018 в 06:30
поделиться
Другие вопросы по тегам:

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