Reputation: 7693
I'd like to define the variable in condition expression so that the variable scope would be within the if
clause. This works fine,
if (int* x = new int(123)) { }
When I was trying to do a similar thing with map::iterator,
if ((map<string, Property>::iterator it = props.find(PROP_NAME)) != props.end()) { it->do_something(); }
I got error: expected primary-expression before ‘it’
What makes the difference between int*
and map::iterator
?
Upvotes: 1
Views: 442
Reputation: 320777
There's no difference between int *
and map::iterator
in that regard. There's a difference in the surrounding semantic constructs that you are using with int *
and map::iterator
, which is why one compiles and other doesn't.
With if
you have a choice of either
if (declaration)
or
if (expression)
Declaration is not an expression. You can't use a declaration as a subexpression in a larger expression. You cannot use a declaration as a part of explicit comparison, which is exactly what you attempt to do.
For example, if you attempted to do the same thing with int *
, like this
if ((int* x = new int(123)) != NULL)
the code would not not compile for exactly the same reasons your map::iterator
code does not compile.
You have to use
if (int* x = new int(123))
or
int* x = new int(123);
if (x != NULL)
or
int* x;
if ((x = new int(123)) != NULL)
As you can see above, int *
exhibits exactly the same behavior as map::iterator
.
In your example, it is impossible to declare it
and perform its comparison with props.end()
in if
s condition. You will have to use one of the above variants instead, i.e. either
map<string, Property>::iterator it = props.find(PROP_NAME);
if (it != props.end())
or
map<string, Property>::iterator it;
if ((it = props.find(PROP_NAME)) != props.end())
Choose whichever you like more.
P.S. Of course, formally you can also write
if (map<string, Property>::iterator it = props.find(PROP_NAME))
but it does not do what you want it to do (does not compare the iterator value to props.end()
) and might not compile at all, since the iterator type is probably not convertible to bool
.
Upvotes: 5
Reputation: 52157
Here is one way to limit it to a scope:
{
auto it = props.find(PROP_NAME);
if (it != props.end()) {
it->do_something();
}
}
Granted, this scope is not technically the "if scope", but should serve just as well for all practical intents and purposes.
As AndreyT already explained (+1), declaration can't transcend (
and )
, which you did not use for int
but you did for the iterator.
Upvotes: 1
Reputation: 253
Map iterators contain first
and second
, which point to the key and value, respectively.
To access a member of the value, use it->second.do_Something()
Upvotes: 0