нужны неконстантные классы выражений в шаблонах выражений - PullRequest
0 голосов
/ 28 декабря 2011

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

В качестве примера рассмотрим шаблон выражения для типа набора set (целых чисел) со стандартным пересечением операций объединения, объединением, отрицанием, xor, разностью и т. Д. Все эти функции имеют эффективные реализации в терминах итераторов, поэтому я хочу, чтобы мои классы шаблонов выражений имели интерфейс, похожий на итератор. Например,

class set_expr_set
{
  set::iter i;

  set_expr_set (const set &s) : i(s) { }

  operator bool () const { return (bool)i; }
  void operator ++ () { i ++; }
  int val () { return *i; }  
}

и затем у меня есть классы шаблонов выражений set_expr_union и т. Д. Теперь проблема в том, что объекты, созданные в соответствии с выражениями шаблонов выражений, являются временными и, следовательно, const, но для оценки выражения мне нужно перебрать значения ( звоните ++ и val), и они неконстантны. Я не могу объявить set::operator = (set_expr &) как неконстантный, потому что временные файлы не будут связывать неконстантный параметр. Я мог бы отбросить константу в operator =, но это не похоже на правильное решение.

У моего примера недостаточно подробностей, чтобы прояснить проблему, я с удовольствием проясню.

РЕДАКТИРОВАТЬ: Вот еще несколько деталей. Предположим, что set_expr_union и set_expr_intersection также имеют вышеуказанный интерфейс: operator ++, val и operator bool. Кроме того, предположим, у меня есть

template<class T>
class set_expr
{
  T t;
  ...;
}

где T предназначен для одного из set_expr_union и т. Д., А set_expr также экспортирует t интерфейс ++, val, bool.

Объекты шаблонов выражений возникают через различные операторы, например ::1010 *

template<class T1, class T2>
set_expr<set_expr_intersection>
operator & (const set_expr<T1> &e1, const set_expr<T2> &e2)
{
  return set_expr<set_expr_intersection> (set_expr_intersection (e1.t, e2.t));
}

Действительно, проблема заключается в временном значении, соответствующем возвращаемому значению от операторов.

Теперь рассмотрим

class set
{
  ...;

  template<class T>
  set &operator = (const set_expr<T> &e)
  {
    clear ();
    for (; e; e ++)
      add_element (e.val ());
  }
};

, который я хочу использовать во что-то вроде set3 = set1 & set2.

Это код, который я хочу написать.

1 Ответ

1 голос
/ 30 декабря 2011

Одно из решений состоит в том, чтобы сделать ваши копии выражений конструктивными и назначаемыми (что не должно быть большой проблемой, если они относительно легки, что, кажется, имеет место). В операторе присваивания набора вы создаете копию выражения набора и перебираете копию.

template<class T>
set& operator=(const set_expr<T> &e) {
  clear ();
  for (set_expr<T> i = e; i; i++) {
    add_element (i.val());
  }
  return *this;
}

Если копирование набора выражений оказывается слишком дорогим, рассмотрите возможность перехода на c ++ 11 и чтения семантики перемещения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...