Я пытаюсь написать шаблон выражения и столкнулся с проблемой, которую не знаю, как решить. Я читал шаблоны 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
.
Это код, который я хочу написать.