emk*_*y08 6 c++ qt const-correctness qlist
A QList<T *>
不容易纠正.考虑这个功能
void f(QList<T *> list)
{
list[0]->constFunction();
}
Run Code Online (Sandbox Code Playgroud)
我可以改变f到
void f(QList<const T *> list)
Run Code Online (Sandbox Code Playgroud)
但后来我不能这样做
f(QList<T *>()); //Compile error
Run Code Online (Sandbox Code Playgroud)
再也没有了,因为编译器不能隐含地强制转换QList<T *>
为QList<const T *>
.但是,我可以明确地重新解释QList,如下所示:
template <typename T> inline QList<const T *> &constList(const QList<T *> &list)
{
return (QList<const T *> &)list;
}
Run Code Online (Sandbox Code Playgroud)
这使我能够使用constList
模板函数将任何内容QList<T *>
转换为a QList<const T *>
,如
f(constList(QList<T *>()));
Run Code Online (Sandbox Code Playgroud)
它似乎工作正常,但实际上这样做是否安全?
你正在考虑的铸造功能,......
template< class T >
inline QList<T const*>& constList( QList<T*> const& list )
{
return reinterpret_cast< QList<T const*>& >(
const_cast< QList<T*>& >( list )
);
}
Run Code Online (Sandbox Code Playgroud)
...可能是实用的(可能QList
不会根据const
元素类型的性质改变其对象表示),但它可能会破坏const
正确性.
首先,因为丢弃const
列表本身的内容是不const
正确的:它允许您更改原始const
列表.
但即使这个正式的论点const
被删除,就像......
template< class T >
inline QList<T const*>& constList( QList<T*>& list )
{
return reinterpret_cast< QList<T const*>& >(
list
);
}
Run Code Online (Sandbox Code Playgroud)
......仍然存在const
正确性问题.
原因是该列表构成了一个额外的间接层,并且您的功能本身并不存在const
.因此,在使用函数获取对具有所谓指向const
元素的列表的引用之后,您可以在该列表中存储指向真实事物的指针const
.然后你可以使用原始列表来修改真正的const
项目,爆炸.
这是同样的原因,也从没有隐式转换T**
到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
);
}
Run Code Online (Sandbox Code Playgroud)
在形式上仍然存在reinterpret_cast
一个潜在的问题,但是任何QList
对元素的常量表示特殊化的人都应该得到他们得到的任何东西.:-)
干杯&hth.,