Qt - QList const正确性

时间:2011-06-26 10:37:28

标签: c++ qt const-correctness qlist

QList<T *>不能轻易纠正。考虑函数

void f(QList<T *> list)
{
    list[0]->constFunction();
}

我可以将f更改为

void f(QList<const T *> list)

然后我不能做

f(QList<T *>());    //Compile error

,因为编译器不能隐含地将QList<T *>强制转换为QList<const T *>。但是,我可以按如下方式明确地重新解释QList:

template <typename T> inline QList<const T *> &constList(const QList<T *> &list)
{
    return (QList<const T *> &)list;
}

这使我能够使用constList模板功能将QList<T *>投射到QList<const T *>中,如

f(constList(QList<T *>()));

它似乎工作正常,但实际上这样做是否安全?

2 个答案:

答案 0 :(得分:8)

您正在考虑的投射功能,......

template< class T >
inline QList<T const*>& constList( QList<T*> const& list )
{
    return reinterpret_cast< QList<T const*>& >(
        const_cast< QList<T*>& >( list )
        );
}

...可能是实际的(可能QList不会根据元素类型的const更改其对象表示),但它可以打破const正确性< / em>的

首先,因为丢弃列表本身的const - 不是const正确的:它允许您更改原始的const列表。

但即使正式论证const被删除,例如......

template< class T >
inline QList<T const*>& constList( QList<T*>& list )
{
    return reinterpret_cast< QList<T const*>& >(
        list
        );
}

...仍有const正确性问题。

原因是该列表构成了一个额外的间接级别,并且您的函数本身不是const。因此,在使用您的函数获取对具有指向指向const元素的列表的引用之后,您可以在该列表中存储指向真正const的内容的指针。然后您可以使用原始列表来修改真正const项目,爆炸

这与no implicit conversion from T** to T const**的原因相同。

如果没有这些问题,你可以做的是,使用已经const指向对象的指针列表,使那些指向对象const

template< class T >
inline QList<T const*> const& constList( QList<T*> const& list )
{
    return reinterpret_cast< QList<T const*> const& >(
        list
        );
}

形式上仍然存在reinterpret_cast作为一个潜在的问题,但任何专注于QList表示元素常量的人都应该得到他们得到的任何东西。 : - )

干杯&amp;第h。,

答案 1 :(得分:3)

Const正确性观念很弱,你找到的是众多原因之一。 Constness概念只捕获一点语义(改变/不改变)并且做得非常糟糕且语法成本相当高,有时甚至需要代码重复。

这个概念的一个问题是它不能通过组合很好地扩展:例如,我可能有兴趣传递一个非const对象的const向量的函数,或者const对象的非常量向量,或者const对象的const向量和正确的语法是昂贵的......只考虑标准c ++如何被迫引入const_iterator,因为这当然不同于const iterator

多年来,我从狂热者的立场出发,在每一个地方使用const正确性,而只是在我被迫使用的地方使用它。经验告诉我,没有痴迷于const正确性的代码变得更清晰,并且const正确性机制永远不会真正捕获(至少对我来说)任何逻辑错误,但只有关于const正确性机制本身的错误。不幸的是,const正确性是C ++中你不得不使用的东西之一,因为C ++规则是这样说的,并且没有办法避免使用它。

我知道我会为这篇文章投票,但我的建议是对你在这个主题上读到的关于C ++的任何内容保持批判态度;保持大脑并客观地判断。只是因为对于某些事情是好的(例如,const正确性有助于程序员),不幸的是它并不意味着它确实是真的。

无论签名这本书有多大。

还要记住,如果一个职位需要世界其他地方都是错的,那么至少有一点怀疑论者可能是一个好主意:大多数语言,即使是那些在C ++之后出生的语言,都没有实现这个概念。 / p>