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;
}
答案 0 :(得分:2)
QVector
要求元素为assignable data types,这意味着它们
必须提供默认构造函数,复制构造函数和赋值 操作
他们的附加版本强制执行所有操作,而如果QTypeInfo<T>::isComplex
为false并且已经过优化,您的版本将不会强制执行 复制构建 。
注意:QTypeInfo<T>::isComplex
在编译时解析。
我怀疑它是遗留的要求,如QVector already existed in Qt2,它在c ++标准化之前的1999
开始。
答案 1 :(得分:2)
我可以想到两个可能的原因。
它遵循stl,copy和swap的其余部分的样式,并通过const&amp ;.在这种情况下,这些都没有任何好的表现或常态的正确性;但它确实保持风格一致。
因为参数绑定到引用,所以它避免了函数调用上的复制省略。并且因为向量中的项必须是可分配的(即不是常量),所以它避免了对赋值的复制省略进入向量
这使代码 MUCH 在编译器中更具可移植性和一致性。对于stl。这可能是一个大问题。
31)当满足某些条件时,允许实现省略类对象的复制/移动构造,即使对象的复制/移动构造函数和/或析构函数具有副作用。在这种情况下,实现将省略的复制/移动操作的源和目标视为仅仅两种不同的引用同一对象的方式,并且该对象的销毁发生在两个对象的后期时间。在没有优化的情况下销毁.123在下列情况下允许复制/移动操作(称为复制省略)的这种省略(可以合并以消除多个副本):
- 当一个尚未绑定到引用的临时类对象时 (12.2)将被复制/移动到具有相同的类对象 cv-unqualified类型,可以省略复制/移动操作 将临时对象直接构造到目标中 省略了复制/移动