QVector :: append()显式复制的原因是什么?

时间:2015-06-11 20:28:46

标签: c++ qt

template <typename T>
void QVector<T>::append(const T &t)
{
    const T copy(t);
    const bool isTooSmall = uint(d->size + 1) > d->alloc;
    if (!isDetached() || isTooSmall) {
        QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow :     QArrayData::Default);
        reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
    }
    if (QTypeInfo<T>::isComplex)
        new (d->end()) T(copy);
    else
        *d->end() = copy;
    ++d->size;
}

使const T copy(t)而不是按值t传递给方法的原因是什么?这和之间有什么区别:

template <typename T>
void QVector<T>::append(const T t)
{
    const bool isTooSmall = uint(d->size + 1) > d->alloc;
    if (!isDetached() || isTooSmall) {
        QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow :     QArrayData::Default);
        reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
    }
    if (QTypeInfo<T>::isComplex)
        new (d->end()) T(t);
    else
        *d->end() = t;
    ++d->size;
}

2 个答案:

答案 0 :(得分:2)

QVector要求元素为assignable data types,这意味着它们

  

必须提供默认构造函数,复制构造函数和赋值   操作

他们的附加版本强制执行所有操作,而如果QTypeInfo<T>::isComplex为false并且已经过优化,您的版本将不会强制执行 复制构建

注意:QTypeInfo<T>::isComplex在编译时解析。

我怀疑它是遗留的要求,如QVector already existed in Qt2,它在c ++标准化之前的1999开始。

答案 1 :(得分:2)

我可以想到两个可能的原因。

  1. 它遵循stl,copy和swap的其余部分的样式,并通过const&amp ;.在这种情况下,这些都没有任何好的表现或常态的正确性;但它确实保持风格一致。

  2. 因为参数绑定到引用,所以它避免了函数调用上的复制省略。并且因为向量中的项必须是可分配的(即不是常量),所以它避免了对赋值的复制省略进入向量

  3. 这使代码 MUCH 在编译器中更具可移植性和一致性。对于stl。这可能是一个大问题。

    Copy Elision Wikipedia Entry

      

    31)当满足某些条件时,允许实现省略类对象的复制/移动构造,即使对象的复制/移动构造函数和/或析构函数具有副作用。在这种情况下,实现将省略的复制/移动操作的源和目标视为仅仅两种不同的引用同一对象的方式,并且该对象的销毁发生在两个对象的后期时间。在没有优化的情况下销毁.123在下列情况下允许复制/移动操作(称为复制省略)的这种省略(可以合并以消除多个副本):

         

    - 当一个尚未绑定到引用的临时类对象时   (12.2)将被复制/移动到具有相同的类对象   cv-unqualified类型,可以省略复制/移动操作   将临时对象直接构造到目标中   省略了复制/移动