表达式模板中需要非常量表达式类

发布于 2024-12-22 20:55:07 字数 1765 浏览 3 评论 0原文

我正在尝试编写一个表达式模板,但遇到了一个不知道如何解决的问题。我读过《C++ 模板:完整指南》,但他们似乎没有解决这个问题。

作为一个例子,考虑一个集合类型 set (整数)的表达式模板,具有标准集合运算交集、并集、求反、异或、差等。这些函数在以下方面都有高效的实现:迭代器,所以我希望我的表达式模板类具有类似迭代器的接口。例如,

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 等。现在的问题是,与表达式模板 expression 相对应创建的对象都是临时对象,因此是 const,但要评估我需要的表达式迭代这些值(调用 ++val),这些值是非常量的。我无法将 set::operator = (set_expr &) 声明为非常量,因为临时变量不会绑定非常量参数。我可以放弃 operator = 中的 const-ness,但这感觉不是正确的解决方案。

我的例子没有足够的细节来阐明问题,我很乐意澄清。

编辑:这里有一些更多细节。假设 set_expr_unionset_expr_intersection 也具有上述接口:operator ++valoperator bool。另外,假设我有

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

其中 T 旨在成为 set_expr_union 等之一,并且 set_expr 还导出 t++ , val, bool 接口。

表达式模板对象是通过各种运算符产生的,例如:

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 & 之类的东西中使用它。设置2。

这就是我想要编写的代码。

I'm trying to write an expression template and I've run into a problem I don't know how to solve. I've read C++ Templates: The Complete Guide but they don't seem to address this question.

As an example, consider a expression template for a set type set (of integers) with the standard set operations intersection, union, negation, xor, difference, etc. These functions all have efficient implementations in terms of iterators, so I want my expression template classes to have an iterator-like interface. For example,

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; }  
}

and then I have expression template classes set_expr_union, etc. Now, the problem is, the objects created corresponding to expression templates expression are all temporaries and therefore const, but to evaluate the expression I need to iterate through the values (calling ++ and val), and these are non-const. I can't declare set::operator = (set_expr &) as non-const, because the temporaries won't bind a non-const parameter. I could cast away the const-ness in operator =, but that doesn't feel like the right solution.

I'm my example doesn't have enough details to make the problem clear, I'll be happy to clarify.

EDIT: Here are some more details. Suppose set_expr_union and set_expr_intersection have the above interface, too: operator ++, val and operator bool. Also, suppose I have

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

where T is intended to be one of set_expr_union, etc. and set_expr also exports t's ++, val, bool interface.

The expression template objects arise through various operators, e.g.:

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));
}

Really, the temporary corresponding to the return value from the operators is where the problem lies.

Now, consider

class set
{
  ...;

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

which I want to use in something like set3 = set1 & set2.

This is the kind of code I want to write.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一身仙ぐ女味 2024-12-29 20:55:07

一种解决方案是使集合表达式副本可构造和可分配(如果它们相对轻量级,这应该不是一个大问题,似乎就是这种情况)。在集合赋值运算符中,您创建集合表达式的副本并迭代该副本。

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 并阅读移动语义。

One solution is to make your set expressions copy constructable and assignable (which shouldn't be a big problem if they are relatively light-weight, which seems to be the case). In the set assignment operator, you create a copy of the set expression and iterate over the copy.

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;
}

If copying the set expressions turns out to be too expensive, consider moving to c++11 and reading up on move semantics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文