简体   繁体   English

std :: for_each()并调用构造函数/析构函数

[英]std::for_each() and calling constructors/destructors

I have problems using for_each() and calling constructors/destructors on each element. 我在使用for_each()并在每个元素上调用构造函数/析构函数时遇到问题。

For reference, mBegin points to the start of the array, mEnd beyond the last element, mCapacity points to the end of allocated memory. 作为参考, mBegin指向数组的开始, mEnd超出最后元件, mCapacity指向分配的存储器的末尾。

template <typename T>
void IDMapTree<T>::Grow()
{
    const size_t prevSize = mCapacity - mBegin;
    const size_t newSize = prevSize != 0 ? static_cast<size_t>(1.5f * prevSize) : 1;
    T* newBuffer = static_cast<T*>(mAllocator.Allocate(newSize));

    // initialize new buffer elements with copy constructor using old elements
    uint32_t itemIndex = 0;
    std::for_each(newBuffer, newBuffer + prevSize, [&](T& item) { item.T(*(mBegin + itemIndex++)); });
    // destruct all old elements
    std::for_each(mBegin, mEnd, [](T& item) { item.~T(); });


    // ...
}

This segment compiles fine: 该段编译良好:

std::for_each(mBegin, mEnd, [](T& item) { item.~T(); });

But this dosn't: 但这不是:

std::for_each(newBuffer, newBuffer + prevSize, [&](T& item) { item.T(*(mBegin + itemIndex++)); });

Not even if I use the default constructor like this: 即使使用这样的默认构造函数也不会这样:

std::for_each(newBuffer, newBuffer + prevSize, [](T& item) { item.T(); });

The compiler (VS2013) says the following: 编译器(VS2013)表示以下内容:

error C2039: '__this' : is not a member of 'JonsEngine::SceneNode'
error C2039: 'T' : is not a member of 'JonsEngine::SceneNode'

In this case, T is of type JonsEngine::SceneNode . 在这种情况下, TJonsEngine::SceneNode类型。

What is the issue here? 这是什么问题? Why dosn't T() resolve to SceneNode() ? 为什么T()解析为SceneNode() Why does the destructor work but not the constructor? 为什么析构函数起作用,而不起作用?

您可以为此使用std::uninitialized_copy()

do it like the stl does it - pass the uninitialized memory chunk as void* ptr and then 像stl一样执行它-将未初始化的内存块作为void* ptr传递,然后

::operator new(ptr) T(item)

item should be passed as const reference. item应作为const引用传递。 (or better - move) (或更好-移动)

char* newBuffer = static_cast<char*>(mAllocator.Allocate(newSize));
if (newSize % sizeof(T) != 0){
  throw std::runtime_error("memory is not alligned");
}
for (size_t i = 0; i< newSize; i += sizeof(T)){
   ::operator new((void*)ptr) T(item)
}

you should also move the objects instead of copy and deleting the old ones. 您还应该移动对象,而不是复制和删除旧对象。 this will also free you from the need to destruct the old objects. 这也将使您摆脱破坏旧物体的需要。

Edit: I don't see why the downvote when this is the correct way to call any constructor on a pre-allocated memory block. 编辑:我不明白为什么当这是在预分配的内存块上调用任何构造函数的正确方法时会降低投票率。 this is the MSVC++ Allocator::construct function which does the same thing 这是MSVC ++ Allocator::construct函数,它执行相同的操作

void construct(_Ty *_Ptr, const _Ty& _Val)
    {   // construct object at _Ptr with value _Val
    ::new ((void *)_Ptr) _Ty(_Val);
    } 

want to downvote MSVC++ reputation as well? 是否也想降低MSVC ++的声誉?

You just need to use placement new. 您只需要使用新的展示位置即可。

btw your use of destructors is fine: 顺便说一句,您可以使用析构函数:

// destruct all old elements
std::for_each(mBegin, mEnd, [](T& item) { item.~T(); });

The expression item.~T(); 表达式item.~T(); is the right way to explicitly call a destructor. 是显式调用析构函数的正确方法。

You cannot call constructors this way. 您不能以这种方式调用构造函数。

So, placement new could be the way to go: 因此,新的放置方式可能是可行的方法:

std::for_each(newBuffer, newBuffer + prevSize, [](T& item) { new (&item) T(); });

btw when using lambdas within a member function you might need to pass this into the capture list. BTW成员函数中使用Lambda表达式时,则可能需要通过this入捕获列表。

Why does the destructor work but not the constructor? 为什么析构函数起作用,而不起作用?

Because destructor belongt to instance and constructot belongs to type. 因为析构函数属于实例,构造函数属于类型。

You can't call the constuctor having the instance, you have to call it using name of the type. 您不能调用具有实例的构造函数,而必须使用类型名称来调用它。 Anyway, you are doing something strange. 无论如何,您正在做一些奇怪的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM