Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Заменить цикл for на for_each с лямбдой


Автор: Aoizora 6.4.2017, 13:17
Есть такой код:

Код

#include <iostream>
#include <string>
#include <memory>
#include <utility>
#include <initializer_list>
#include <algorithm>

class StrVec
{
public:
    StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {}
    StrVec(const StrVec &);
    StrVec(std::initializer_list<std::string> il);
    StrVec& operator=(const StrVec &);
    ~StrVec();

    void push_back(const std::string &);
    std::size_t size() const { return first_free - elements; }
    std::size_t capacity() const { return cap - elements; }
    std::string *begin() const { return elements; }
    std::string *end() const { return first_free; }

private:
    std::allocator<std::string> alloc;
    void check_and_alloc()
    {
        if (size() == capacity()) reallocate();
    }
    std::pair<std::string *, std::string *> alloc_and_copy(const std::string *, const std::string *);
    void free();
    void reallocate();

    std::string *elements;
    std::string *first_free;
    std::string *cap;
};

void StrVec::push_back(const std::string &s)
{
    check_and_alloc();
    alloc.construct(first_free++, s);
}

std::pair<std::string *, std::string *>
StrVec::alloc_and_copy(const std::string *b, const std::string *e)
{
    auto data = alloc.allocate(e - b);
    return { data, std::uninitialized_copy(b, e, data) };
}

void StrVec::free()
{
    if (elements)
    {
        /*for (auto p = first_free; p != elements; )
            alloc.destroy(--p);*/
        std::for_each(elements, first_free, [&](auto &s) { alloc.destroy(s) });
        alloc.deallocate(elements, cap - elements);
    }
}


Я хочу переписать функцию free с использованием цикла for_each и лямбды. Здесь я сделал проход от первого элемента (elements) до первого после последнего (first_free) и для каждого элемента хочу вызвать функцию освобождения памяти, занятой этим элементом: alloc.destroy. Аллокатор передаю в лямбду по ссылке. Однако мой код не компилируется: C2672: 'std::allocator<std::string>::destroy': no matching overloaded function found.

Как правильно составить лямбду?

Автор: azesmcar 6.4.2017, 13:49
Код

alloc.destroy(&s)

std::for_each передает результат разыменования итератора (в твоем случае указателя), т.е. ссылку, в то время как destroy принимает указатель.
Цитата

http://en.cppreference.com/w/cpp/algorithm/for_each
Applies the given function object f to the result of dereferencing every iterator in the range

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)