Reputation: 1897
I have a program to verify if an IPv4 address entered as string is in valid dotted-quad notation.
The problem I am facing is that I'm not able to return (exit) function once I detect error. As per cppreference documentation for_each returns UnaryFunction. I tried using any_of and all_of but they require me using an loop (range-based loop) inside my lambda function which I'm trying to avoid. Am I missing something or it is not possible to return value in for_each.
vector<string> ipExplode;
string ip;
bool inValidIp = false;
cout << "Server IP : ";
cin >> ip;
trim(ip);
ipExplode = explode(ip, '.');
if(not for_each(ipExplode.begin(), ipExplode.end(), [](const string& str) -> bool{
int32_t ipNum;
if(regex_search(str, regex("\\D+")))
return false;
try
{
ipNum = stoi(str);
if(ipNum < 0 or ipNum > 255)
return false;
}
catch (std::exception& ex)
{
return false;
}
}))
return false;
Upvotes: 6
Views: 1544
Reputation: 75688
You shouldn't use for_each
anyway. Replace it by the ranged-based for and it all becomes so much simpler and elegant. Put it all in a function and there you go:
auto is_ip_valid(const std::vector<std::string>& ipExplode)
{
for (auto&& str : ipExplode)
{
// ...
}
}
Upvotes: 0
Reputation: 21917
from for_each
:
If f returns a result, the result is ignored.
i.e. there is no point in returning a value from your for_each
lambda.
A good choice here is all_of
, which accepts a UnaryPredicate
rather than a UnaryFunction
, since you want to make sure that all of the parts of the string pass the lambda successfully:
bool isValid = std::all_of(ipExplode.begin(), ipExplode.end(), [](const std::string& str) -> bool{
if(regex_search(str, regex("\\D+")))
return false;
try
{
int32_t ipNum = stoi(str);
if(ipNum < 0 or ipNum > 255)
return false;
}
catch (std::exception& ex)
{
return false;
}
return true;
});
all_of
will stop iterating once an invalid part is found.
Upvotes: 9
Reputation: 16404
Am I missing something or it is not possible to return value in for_each.
for_each
does return the UnaryFunction
. But if you put a unary function to if
expression, its meaningless.
In your case, a lambda without capturing can implicitly convert to a function pointer. A non-null function pointer as a boolean value is always true
. Thus your
if(not for_each( /* ... */ ))
will be evaluated to false
all the time.
As commentators and other answerers have already written, std::all_of
is what you want here.
Upvotes: 1