【问题标题】:Writing a sort() method for a vector class为向量类编写 sort() 方法
【发布时间】:2012-09-30 15:31:13
【问题描述】:

我正在编写自己的向量类 Vector,其数据成员为:T* 数组、size_t vector_size 和 size_t 容量。我正在尝试创建一个 sort() 方法:

template <class T>                                                                                                 
void Vector<T>::sort(bool ascending)                                                                                 
{                                                                                                                   
    std::sort(array,array+vector_size);                                                                              
    if(ascending==false)                                                                                             
        std::reverse(array,array+vector_size);                                                                      
}   

当数组中的元素是 int、char 等类型时,它可以正常工作。但是当我尝试对由 Vector 元素组成的向量进行排序时,它不会编译。 根据我的阅读,我需要以某种方式定义 &lt;operator,但我真的不知道该怎么做......

我试过了:

template <class T>
bool Vector<T>::operator<(Vector<T> & source) const
{
    return (vector_size < source.vector_size);
}

我的主要样子是这样的:

int main() {
    Vector<int> v1(5,1);
    Vector<int> v2(7,2);
    Vector<int> v3(3,3);
    Vector<Vector<int>> v4;
    v4 = {v1,v2,v3};
    v4.sort(1);
return 0;
}

这是我得到的错误之一:

/usr/include/c++/4.6/bits/stl_algo.h:2212:4: error: no match for ‘operator

【问题讨论】:

  • 请注意,语法 Vector&lt;Vector&lt;int&gt;&gt; 仅从 C++11 标准开始受支持,如果您想支持非 C++11 编译器,则应避免使用该语法。 “旧”语法需要在 &gt;&gt; 之间留一个空格以区别于右移运算符:Vector&lt;Vector&lt;int&gt; &gt;
  • ...但如果您需要 C++11 支持,请使用 lambdas 作为比较! ;) stackoverflow.com/q/7767998/592323

标签: c++ templates sorting vector operator-keyword


【解决方案1】:

您提供了带有错误签名的比较方法。您需要接受 const 引用或值,但不是对您的类型的(可修改)引用,而前者应该是首选,除非它是原始类型。所以你的比较方法的签名应该是这样的:

template <class T>
bool Vector<T>::operator<(const Vector<T> & source) const
{
    return (vector_size < source.vector_size);
}

这是因为std::sort(以及许多其他方法)旨在不修改内容。如果它们采用值(但对于大型类型来说这会很慢)或 const 引用,则可以保证这一点。

请注意,您定义了比较方法来比较向量的大小,而不是它们的内容。你所有的向量都是等长的。因此,std::sort 将它们视为平等。所以std::sort 不会改变v4...如果您打算以类似于字符串比较的方式比较内容(第一个条目首先计数,如果相等则采用下一个,依此类推...),请使用这个:

template <class T>
bool Vector<T>::operator<(const Vector<T> & source) const
{
    for(int i = 0; i < size && i < source.size; ++i) {
        if(*this[i] < source[i])
            return true;
        else if(source[i] < *this[i])
            return false;
    }
    // You have to decide what to do if the length isn't equal.
    // But if the vectors are really equal than return false:
    if(size == source.size)
        return false;
}

【讨论】:

  • 谢谢!它们实际上的长度不同,5,7 和 3。所以它有效。
【解决方案2】:

你忘记了一个常量!

template <class T>
bool Vector<T>::operator<(const Vector<T> & source) const // <- here
{
    return (vector_size < source.vector_size);
}

【讨论】:

    【解决方案3】:

    您需要在操作员的参数中使用const,否则它无法匹配任何只读的内容(这是常见的情况)。

    请记住,尽管每次交换发生时,对向量的向量进行排序会复制整个向量。这不会特别有效。如果向量是分开存储的,并且你有类似vector-of-pointer-to-vector的东西,至少排序会更快。

    请务必阅读“严格弱排序”的定义。排序与自身保持一致非常重要,否则标准算法(如 std::sort() 可能会出现严重的错误行为(在某些实现中会破坏内存)。

    【讨论】:

    • 这个比较方法是不是一致的?
    • 在 C++11 中,交换向量并不是什么大问题,因为交换会移动它们而不是复制它们。
    猜你喜欢
    • 2011-02-19
    • 2014-02-23
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    相关资源
    最近更新 更多