Home > Back-end >  Using count_if() to find the same string value
Using count_if() to find the same string value

Time:11-17

I tried using a lambda expression and count_if() to find the same string value in a vector, but it didn't work. The error message is:

variable 'str' cannot be implicitly captured in a lambda with no capture-default specified

std::vector<std::string> hello{"Mon","Tue", "Wes", "perfect","Sun"};

for (unsigned int i = 0; i < hello.size(); i  )
{
    int n=0;
    std::string str=hello[i];
    n=std::count_if(hello.begin(),hello.end(),[](std::string s){return s==str;});
    std::cout<<n;
}

CodePudding user response:

@Steven The brackets [] of lambda functions, are called a capture list. They define the scope of variables that the lambda function uses. See this reference.

When you use this formatting [&], it means you can see all the variables (by reference) of the current scope in your lambda function. So the type of variables doesn't matter.

For your example, when you write:

s == str

The lambda function only knows about the variable s, which is passed as an argument. To see the str, you can use either of these:

  1. [&], pass everything by reference
  2. [&str], pass only the variable str as reference

Note, there are also ways to pass by value.

CodePudding user response:

  This function has the same mechanism, only it uses <hash> and <unordered_map> to store the values and the number of times each is repeated (if it is greater than 1 occurrence).

template <typename T>
void elements(vector<T>& e) 
{
    auto h = [](const T* v) { return std::hash<T>()(*v); };
    auto eq = [](const T* v1, const T* v2) { return v1->compare(*v2) == 0; };
    std::unordered_map<const T*, size_t, decltype(h), decltype(eq)> m(e.size(), h, eq);

    // Count occurances.
    for (auto v_i = e.cbegin(); v_i != e.cend();   v_i)
          m[&(*v_i)];

    // Print value that occur more than once:
    for (auto m_i = m.begin(); m_i != m.end();   m_i)
        if (m_i->second > 1)
            std::cout << *m_i->first << ": " << m_i->second << std::endl;
}

  Example

  • Related