QList<T *>
不能很容易是const正确的。考虑功能
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 *>()));
似乎工作正常,但是这样做确实安全吗?
最佳答案
您正在考虑的转换功能,…
template< class T >
inline QList<T const*>& constList( QList<T*> const& list )
{
return reinterpret_cast< QList<T const*>& >(
const_cast< QList<T*>& >( list )
);
}
…可能是实用的(取决于元素类型的
QList
-ness,const
可能不会更改其对象表示形式),但它可能会破坏const
的正确性。首先,因为舍弃列表本身的
const
-ness并不是正确的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
项 bang 。这就是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
表示元素常量的人都应该得到他们所得到的一切。 :-)干杯,……