An example is provided to illustrate the problems described in this article. The specific code is:
Deque <string> test;
Copy (istream_iterator <string> (cin), istream_iterator <string> (), back_inserter (test ));
The above Code clearly states a deque <string> container named test first, and initializes it as null. Then, push the strings read from the standard input stream (cin) into the container with spaces until there are no more available input. It is equivalent:
Deque <string> test;
Istream_iterator <string> first (cin), last;
Copy (first, last, back_inserter (test ));
Let's take a look at the following statement to declare a deque <string> container with the same name as test.
Deque <string> test (istream_iterator <string> (cin), istream_iterator <string> ());
The intention of writing the preceding statement is the same as the previous intention. The strings read from the standard input stream (cin) are pushed into the container with spaces until there are no more available input. However, we want to call the deque <string> constructor that accepts a pair of iterators as parameters to implement its functions. Can it complete the functions we have imagined?
In fact, "deque <string> test (istream_iterator <string> (cin), istream_iterator <string> ();" only declares a function named test, in addition, the return value type is deque <string>, and there are two parameters to be passed in. The first one is the parameter of the type istream_iterator <string> and the parameter named cin, the second is an anonymous parameter that does not accept any parameters. It does not implement the desired "declare a deque <string> object named test, and initialize it through a pair of iterator passed in ". Why is this happening?
Reference the c ++ 03 standard original statement: When the syntax form of the declaration and expression statements may be ambiguous, that is, a function-style explicit type conversion is an expression statement used as its leftmost subexpression and a declaration statement whose first declaration sub starts with "(" may not be separated. In this case, the statement is interpreted as a declaration.
In short, when the Declaration and expression meanings occur, the compiler always resolves them as declarations.
How can this problem be avoided?
Since this is caused by the ambiguity between syntax forms, you can "modify" the statement as an illegal statement to eliminate the ambiguity. To completely get rid of the ambiguity, do not use the syntax that will make some compilers mistakenly think of as declared. There are two methods:
1. Avoid letting the compiler recognize it as a function declaration. The direct approach is:
Deque <string> test (istream_iterator <string> (cin), (istream_iterator <string> ()));
By adding extra brackets to the parameters, we will prompt the compiler to provide constructors instead of parameter declarations. Redundant parentheses make this form of code impossible to be interpreted as legal declaration statements.
2. Use the named variable as the parameter of the constructor to completely avoid the ambiguity of the declared statement.
Istream_iterator <string> first (cin), last;
Deque <string> test (first, last );
Obviously, the code in method 2 is clearer and easier to maintain. Therefore, it is best to use method 2 to avoid the ambiguity of declarations and statements.