【问题标题】:Template specialization for std::less in C++11, using a templateC++11 中 std::less 的模板特化,使用模板
【发布时间】:2015-08-28 07:17:33
【问题描述】:

我有一个派生自 Eigen 模板的 Matrix 类:

template<typename T,
         int _Rows = Eigen::Dynamic,
         int _Cols = Eigen::Dynamic>
class Matrix : public Eigen::Matrix<T, _Rows, _Cols>

我需要将此类型用作std::map 容器的键,因此我需要一个比较器对象。我想专门为此目的std::less。不编译的草稿版本如下所示,让您了解一下:

template<typename Matrix<typename T,
                         int _Rows = Eigen::Dynamic,
                         int _Cols = Eigen::Dynamic> > >
struct less
{
    bool operator()(const Matrix<T,
                                 Rows,
                                 Cols>& lhs,
                    const Matrix<T,
                                 Rows,
                                 Cols>& rhs) const;
    {
      Matrix<T,
             Rows,
             Cols>::const_iterator lhsIt = lhs.begin();
      Matrix<T,
             Rows,
             Cols>::const_iterator rhsIt = rhs.begin();
      for (;
           lhsIt != lhs.end();
           ++lhsIt, ++rhsIt)
      {
        if (*lhsIt < *rhsIt)
        {
          return true;
        }
      }
      return false;
    }
};

问题是我想使用模板专门化std::less。对此进行编码的正确方法是什么?我必须求助于模板专业化吗?

我还需要以类似的方式专门化 std::hash 才能使用 std::map

【问题讨论】:

  • template&lt;typename T, int _Rows, int _Cols&gt; struct less&lt;Matrix&lt;T, _Rows, _Cols&gt; &gt;
  • 如果你只是在你的 Matrix 类中实现 less 操作符呢?用它作为map中的key就足够了
  • @TomKnapen 除了 _Rows_Cols 是保留标识符

标签: c++ templates c++11 stl eigen


【解决方案1】:

问题是我想使用模板专门化std::less

不要。 std::less 的意思是“为此类调用 &lt; 运算符”;将其专门用于没有 &lt; 运算符的类会不必要地混淆阅读您的代码的其他人,而将其专门用于具有 &lt; 运算符的类是毫无意义。

只需实现一个正确的operator&lt; 重载,就可以在std::map 中使用它。

我还需要以类似的方式专门化 std::hash 才能使用 std::map

不,你没有。只有unordered_map 才需要。

顺便说一句,你的比较算法是错误的。它报告[2, 1] &lt; [1, 2] [1, 2] &lt; [2, 1]。更不用说它无法处理两个矩阵具有不同数量元素的情况。

【讨论】:

  • Stepanov 和 McJones 在 Elements of Programming 中区分 &lt;std::less。他们使用std::less 作为可能没有自然总排序的类型的默认总排序,例如复数(虽然 AFAIK std::complex 没有提供这样的特化,但指针的特化是众所周知的)。
  • 感谢您的建议。实施很简单。我还在比较中添加了测试用例 *lhsIt > *rhsIt。目前不需要比较各种大小的矩阵。
  • @dyp 我个人认为less 等指针的特化更多是核心语言损坏的补丁,就像div 在很大程度上是损坏除法/模运算符的补丁在 C89/C++98 中。
【解决方案2】:

正确的语法是

template <typename T, int Row, int Col>
struct less<Matrix<T, Row, Col>>
{
    bool operator()(const Matrix<T, Row, Col>& lhs,
                    const Matrix<T, Row, Col>& rhs) const
    {
        // implementation:
        return lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
    }
};

这是一个专业化。

顺便说一句,您的实现不尊重较少的要求:(它不是对称的)。

【讨论】:

  • 感谢部分专业化的描述。
  • 很好地使用lexicographical_compare (+1)。
猜你喜欢
  • 2022-07-05
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多