在Qt中正确使用C ++ 11基于范围的for循环 [英] Using C++11 range-based for loop correctly in Qt

查看:189
本文介绍了在Qt中正确使用C ++ 11基于范围的for循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据这次讲座,有一个在Qt容器上使用C ++ 11范围库 for 时的某些缺陷。考虑:

  QList< MyStruct>列表; 

for(const MyStruct& item:list)
{
// ...
}
pre>

根据谈话,陷阱来自隐式共享。在引擎盖下,基于范围的获取从容器的迭代器。但是因为容器不是const,所以interator将是非常量,这显然足以使容器分离。



当你控制容器的生命周期时,这是容易修复,一个只是通过const引用容器,强制它使用const_iterator和不分离。

  QList< MyStruct>列表; 
const Qlist< MyStruct> & constList = list;

for(const MyStruct& item:constList)
{
// ...
}
pre>

但是例如容器作为返回值。

  QList< MyStruct> foo(){// ...} 

void main()
{
for(const MyStruct& item:foo())
{
}
}

容器是否仍被复制?直观地,我会说这是为了避免这可能需要做。

  QList< MyStruct> foo(){// ...} 

main()
{
for(const MyStruct& item:const_cast< const QList< MyStruct> )))
{
}
}

当然。我知道这是一个有点更冗长,但我需要这是因为我使用范围基于对巨大的容器上的循环很多,所以这种谈话类型与我正确的字符串。



到目前为止,我使用一个辅助函数将容器转换为const引用,但如果有一个更简单/更短的方法来实现相同的,我想听到它。

解决方案

 模板< class T& 
std :: remove_reference_t< T>常数& as_const(T& t){return t;}

隐式共享对象返回的值可以隐式地检测由于非const迭代造成的写剔除(和detatch)。



这会给你:

  for(auto&& item:as_const(foo()))
{
}



它可以让你以一种const方式(非常清楚)进行迭代。



如果您需要参考有效期延长工作,有2个重载:

 模板< class T& 
T const as_const(T& t){return std :: forward< T>(t);}
template< class T>
T const& as_const(T& t){return t;}

但是遍历const值和关心它经常一个设计错误:他们被丢弃的副本,为什么它重要,如果你编辑他们?如果你的行为方式不同,基于const限定,那将在其他地方咬你。


According to this talk there is a certain pitfall when using C++11 range base for on Qt containers. Consider:

QList<MyStruct> list;

for(const MyStruct &item : list)
{
    //...
}

The pitfall, according to the talk, comes from the implicit sharing. Under the hood the ranged-based for gets the iterator from the container. But because the container is not const the interator will be non-const and that is apparently enough for the container to detach.

When you control the lifetime of a container this is easy to fix, one just passes the const reference to the container to force it to use const_iterator and not to detach.

QList<MyStruct> list;
const Qlist<MyStruct> &constList = list;

for(const MyStruct &item : constList)
{
    //...
}

However what about for example containers as return values.

QList<MyStruct> foo() { //... }

void main()
{
    for(const MyStruct &item : foo())
    {
    }
}

What does happen here? Is the container still copied? Intuitively I would say it is so to avoid that this might need to be done?

QList<MyStruct> foo() { //... }

main()
{ 
    for(const MyStruct &item : const_cast<const QList<MyStruct>>(foo()))
    {
    }
}

I am not sure. I know it is a bit more verbose but I need this because I use ranged based for loops heavily on huge containers a lot so the talk kind of struck the right string with me.

So far I use a helper function to convert the container to the const reference but if there is a easier/shorter way to achieve the same I would like to hear it.

解决方案

template<class T>
std::remove_reference_t<T> const& as_const(T&&t){return t;}

might help. An implicitly shared object returned an rvalue can implicitly detect write-shraring (and detatch) due to non-const iteration.

This gives you:

for(auto&&item : as_const(foo()))
{
}

which lets you iterate in a const way (and pretty clearly).

If you need reference lifetime extension to work, have 2 overloads:

template<class T>
T const as_const(T&&t){return std::forward<T>(t);}
template<class T>
T const& as_const(T&t){return t;}

But iterating over const rvalues and caring about it is often a design error: they are throw away copies, why does it matter if you edit them? And if you behave very differently based off const qualification, that will bite you elsewhere.

这篇关于在Qt中正确使用C ++ 11基于范围的for循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆