Terms 6: Beware C Another Confusion Analysis
If you have an integer component, you need to copy it into a list. The following code looks a very meaningful method:
IFStream DataFile ("INTS.DAT");
List
Data (istream_iterator
(DataFile), // Warning! This Doesn't Do
iStream_iterator
())
// What you think it does
The idea here is to deliver a pair of ISTREAM_ITERATOR to the interval constructor of the List (see item 5) to turn integers in the file.
Copy to the list.
This code can be compiled, but at runtime, it does not do anything. It does not read any data from the file. It does not create a list.
Because the second statement does not declares a list, there is no call constructor. What did it do? .. It is so weird.
I don't dare to tell you directly, you won't believe it. I can only explain a little bit. Are you sitting? If you don't have to find a chair.
We started from the most basic. This line of code declares a function f, which has a Double type parameter that returns an int type value.
INT F (Double D);
The following lines play the same role. The parentheses on both sides of the parameter D are redundant and will be ignored.
INT F (Double (D)); // Same As Above; Parens Around D Are Ignored
This line code declares the same function. It did not miss the parameter name.
INT F (Double); // Same as Above; parameter name is omitted.
You may be very familiar with the above three statements. Although the ability to put the parameter name in parentheses is very fresh. (I have been fresh for me for a long time)
Look at three functions declaration. The first declares a function with a function pointer parameter. This function pointer points to a function of unlucked and returns a Double type.
INT G (Double (* pf) ()); // g takes a Pointer to a function as a parameter
This has another method. The only difference is that PF uses non-polar syntax (which is valid in C and C )
INT G (Double PF ()); // Same as Above; PF is Implicitly a Pointer;
As in us, the parameter name can be omitted. Since this is the method of the third declaration G, the name PF is eliminated.
INT G (Double ()); // Same as Above, Parameter Name IS OMIMITTED
Note that the brackets are on the parameter name (D) in the second declaration of F) and only parentheses (this example). Brackets on the parameter name will be ignored, but only parentheses indicate a list of parameters: they indicate that the parameters appearing here are pointers that are pointing functions.
After the statement of F and G, you can take a look at the code of the beginning. Rapidly listed here:
List
Data (istream_iterator
(DataFile), istream_iterator
())
Picking up the spirit, this line code declares a function, named DATA, its return type is List
. Function Data has two parameters:
The first parameter is called DataFile. Its type is iStream_iterator
. Brackets on both sides of DataFile are ignored.
The second parameter has no name. Its type is the pointer to the function, the point to which the function type is no, the return value type is iStream_iterator
.
Is it surprising? However, it illustrates a common rule of C , which will be parsed as a function declaration as much as possible. If you have used C for a while, you must have encountered other forms of declaration of this rule. How many times have you found this mistake? Class Widget {...}; // Assume Widget Has A Default Constructionor
Widget w (); // 'uh oh ...
This did not declare a widget called W, which declarested a named W None function, which returned to a Widget. Learning and knowing this is like a truly C programmer.
These are interesting (on the form of it), but it can't help us declare what we hope to get: Define a list
The object is initialized by the content of the file. Now we know how to prevent it from being parsed, which is easy to say. C is not allowed to put the shape within parentheses, but the parameters called the function call can bring parentheses. For some additional parentheses can force the compiler to read code in our way.
List
Data ((iStream_Iterator)
(DataFile))
// Note New Parens
iStream_iterator
0);
// around first argument
// to List's Constructor
This form is declared DATA, using the ISTREAM_ITERATOR tool to define a set of intervals, using interval constructors. (Once again, see Terms 5), it is worth doing so.
Unfortunately, not all compilers know this. I have tested some compilers, and half of the DATA declaration (correct form) unless the incorrect form without attach parentheses.
.
In order to appease these compilers, you only have your eyes, using my painful description as the wrong statement. But this is not portable and is also short-sighted. Finally, now analyzing the wrong compiler will always correct, right? (of course)
The best solution is to simply give the name of these iterators simply in the Data statement. The following code can work anywhere:
IFStream DataFile ("INTS.DAT"};
iStream_iterator
DATABEGIN (DataFile);
iStream_iterator
DataEnd;
List
Data (DATABEGIN. DATAEND);
This code is universal
STL
Different styles, it uses named iterator objects, but you need to decide whether to use the code for compilers and programmers worthwhile.