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:
[&]
, pass everything by reference[&str]
, pass only the variablestr
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;
}