【问题标题】:How to implement a simple < operator如何实现一个简单的 < 运算符
【发布时间】:2014-05-01 14:08:03
【问题描述】:

我有一个包含几个简单成员的类,并且想实现一个非常简单的&lt; 运算符。这是我开始的:

inline bool operator< (const T& lhs, const T& rhs)  { return std::tie(lhs.GetA(), lhs.GetB()) < std::tie(rhs.GetA(), rhs.GetB()); }

Visual Studio 抱怨

Warning 2   warning C4239: nonstandard extension used : 'argument' : conversion from 'A' to 'A &'

似乎问题在于我没有使用成员,而是使用函数,并且正在将右值传递给非常量引用。我想我可以将 GetA() 保存在本地 A 中,但我宁愿不这样做。

我该如何解决这个问题?

我尝试添加

A& GetARef() const { return a; }

这不起作用,因为我试图用 const 返回一个非常量引用。

A& GetARef() { return a; }

这不起作用,因为 lhsrhs 是 const。

现在我在想也许我应该使用std::tuple 或者std::tie( std::cref(lhs.GetA()) ),或者也许是一个新模板

template < typename... T >
std::tuple<const T&...> ctie( const T&... args )
{
    return std::tie( args... );
}

但我不禁觉得我把这件事复杂化了……

【问题讨论】:

  • 你试过用std::forward_as_tuple代替std::tie吗?
  • 试试const A&amp; GetARef() const
  • 两者都有效。请不要在 cmets 中回答。

标签: c++ c++11 operator-overloading


【解决方案1】:

tie 生成 lvalue 引用的元组,因此不适用于临时对象(除非它们是 const,因此对元组类型的推导给出了 const 引用)。

您可以使用 make_tuple 创建对象元组,或使用 forward_as_tuple 根据参数的值类别获取 lvaluervalue 引用。

或者,您可以通过将const 引用返回到const 成员来使您的访问器工作:

A const & GetARef() const { return a; }
  ^^^^^

【讨论】:

  • 标准推荐似乎是std::tie。那么forward_as_tuple 总是更合适吗?
  • @Cookie:通常将tie 与成员变量本身一起使用,以提供一个简洁明了的实现。如果您坚持将它们隐藏在访问器后面,那么要么 (a) 让操作符成为朋友,要么 (b) 将访问器更改为返回 (const) 引用,让调用者选择是否复制它们,或者 (c) 使用forward_as_tuple处理无偿复制的对象。
  • 我认为简单地修复 getter 是解决问题的方法。
  • @R.MartinhoFernandes:我同意(与 goo 一起),返回对内部的引用很便宜,但这意味着 A 不再是实现细节,因为它作为界面的一部分公开。副本虽然效率较低,但也可以成为从头开始创建的对象,从而提供更大的灵活性。
猜你喜欢
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多