0

I'm just trying to get the iterator over a vector of strings, getting the iterator passed to 'pos' and transfered together with the value at pos to another function, but the compiler tells me there was an invalid conversion at the lambda argument from 'const char*' to 'size_t'. I'm also getting this for header stl_algo.h:

no match for call to '(prototype::Monitor::setOptions(size_t)::<lambda(int)>) (const char&)' __f(__first);

#include <iostream>
#include <Windows.h>
#include <string.h>
#include <map>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cstdio>
.
.
void setOptions(size_t id) {
    switch(id){
        case 0:
            std::for_each(main_menu.lines.begin(), main_menu.lines.end(),[this](size_t pos){
                this->setOption(pos, main_menu.lines[pos]);
            });
            break;
        case 1:
            break;
    }
}

Being all of these inside a class referred by 'this', and setOption is different from setOptions. I've read in other places that it should be fine if it would just convert the iterator for the string pointer to an int, i've also seen examples being used like that.

I also know this whole thing isn't probably the best way to do this, but i've just come to c++ and i'm trying to use some things i learned.

Win10 64bit - gcc (MinGW.org GCC-6.3.0-1)

1
  • And what specifically are you asking? Take a look at the reference for std::for_each, that's not how it works. There are also examples there. Basically the lamda takes elements of the iterated range as parameter, not indices, not iterators. Commented Dec 23, 2020 at 8:28

1 Answer 1

1

When iterating a vector of strings with std::for_each(), the parameter passed to the lambda will be a string, not a size_t index. That is why you are getting a conversion error.

If you need an index, then you will have to change your lambda to track the index separately, eg:

size_t pos = 0;
std::for_each(main_menu.lines.begin(), main_menu.lines.end(),
    [&,this](const string &s){ this->setOption(pos++, s); }
);

Otherwise, simply don’t use std::for_each() to begin with, eg:

for(size_t pos = 0; pos < main_menu.lines.size(); ++pos){
    setOption(pos, main_menu.lines[pos]);
}
Sign up to request clarification or add additional context in comments.

3 Comments

You can also include the pos into the lambda: [this, pos = 0](const string&) mutable { ... }.
@DietmarKühl true, though the type of pos in that case will be int, not size_t. You would have to use [this, pos = size_t{0}] instead.
So you'd use pos = std::size_t() or pos = std::string::size_type() if that matters for your use case. The more interesting bit would be writing this with ranges which should be something like std::ranges::for_each(zip(main_menu.list, std::ranges::iota(std::size_t()), [this](const std::string& s, std::size_t pos){ ... }); Caveat: there is no zip() [yet].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.