From the book named <<Effective STL 50 Specific Ways to Improve Your Use of the Standard Template Library>>, I knew the suggestion of " Watch out the parsing mechanism of C++ compiler", which is the sixth suggestion in that book. This fact is because of C++ using the strategy of "interpreted as being function as possible".
There is a classic and typical example about reading data from a file and using the data as parameters to construct a list.
The code is below:
#include <iostream> #include <fstream> #include <list> #include <iterator> using namespace std; int main(int argc, char* argv[]) { std::ifstream dataFile( "Test.txt" ); std::list< int > intData( std::istream_iterator< int >( dataFile ), std::istream_iterator< int >() ); std::list< int >::iterator iter = intData.begin(); for(iter; iter != intData.end(); ++iter) { std::cout<<*iter<<std::endl; } return 0; }
If you use this code compiled with gcc 4.4.7, you will get below output:
parseMech.cc:19: error: request for member ‘begin’ in ‘intData’, which is of non-class type ‘std::list<int, std::allocator<int> >(std::istream_iterator<int, char, std::char_traits<char>, int>, std::istream_iterator<int, char, std::char_traits<char>, int> (*)())’
It says we are using a non-class type, which means what we want to construct a list above is not valid.
So It's important for us to explore how the compiler deals with the statement of definition of the variable iniData. Here C++ Compiler uses the strategy which introduced above to interpret the definition as a declaration of a function. It treats the dataFile as a parameter with type of std::istream_iterator<int> and treats the std::istream_iterator<int>() as a function pointer which points to a function having no parameter and return type of std::istream_iteratior<int>.
Now we know what the C++ Compiler actually do , then what we can do to avoid this mechanism of C++ Compiler?
There are two solutions to solve this problem:
1. wrapped the std::istream_iterator<int>(dataFile) with pair of parentheses. the result is
#include <iostream> #include <fstream> #include <list> #include <iterator> using namespace std; int main(int argc, char* argv[]) { std::ifstream dataFile( "Test.txt" ); std::list< int > intData(( std::istream_iterator< int >( dataFile )), std::istream_iterator< int >() ); std::list< int >::iterator iter = intData.begin(); for(iter; iter != intData.end(); ++iter) { std::cout<<*iter<<std::endl; } return 0; }
Then we re-compile this code and the damn error would be gone. But unfortunately, this solution is not well supported by all of compilers. So We will introduce the other solution.
2. The better solution is to avoid using anonymous object, the following code would always work correctly:
#include <fstream> #include <list> #include <iterator> using namespace std; int main(int argc, char* argv[]) { std::ifstream dataFile( "Test.txt" ); std::istream_iterator< int > dataBegin(dataFile); std::istream_iterator< int > dataEnd; std::list< int > intData(dataBegin, dataEnd ); std::list< int >::iterator iter = intData.begin(); for(iter; iter != intData.end(); ++iter) { std::cout<<*iter<<std::endl; } return 0; }
Here we explicitly declare the dataBegin and dataEnd.
相关推荐
Aho and Ullman - The Theory of Parsing, Translation, and Compiling - Vol. 1 (1972).djvu Aho and Ullman - The Theory of Parsing, Translation, and Compiling - Vol. 2 (1973).djvu
Enhanced the implementation of the "serialized mode" of the interpreter (enabled via the AcpiGbl_AllMethodsSerialized flag.) When this mode is specified, instead of creating a serialization semaphore ...
The proliferation of processors, environments, and constraints on systems has cast compiler technology into a wider variety of settings, changing the compiler and compiler writer's role. No longer is ...
how to get a readable and programmable result from the IL array provided by the MethodBody.GetILAsByteArray() method.
《深入解析YARD C++解析框架》 YARD(Yet Another Recursive Descent)是一个专为C++设计的开源解析框架,其目标是提供一个高效、灵活且易于使用的工具,用于处理语言解析和编译任务。这个框架的核心在于递归下降...
* Added the possibility to modify the value of a variable during debugging (right click on a watch variable and select "Modify value") * During Dev-C++ First Time COnfiguration window, users can now ...
Parsing JSON in Swift will teach you to harness the power of Swift and give you confidence that your app can gracefully handle any JSON that comes its way. You'll learn: - How to use ...
C++ parsing DSL(领域特定语言解析)是编程领域中的一个重要概念,主要涉及到如何在C++中解析和处理特定领域的语法或指令集。DSL是一种为特定任务设计的简化语言,它可以嵌入到像C++这样的通用编程语言中,使得代码...
By creating a simplified version of a C compiler, the author aims to demonstrate the core concepts involved in building a compiler. This includes defining a grammar for the language, parsing the ...
The new, expanded version of this textbook describes all phases of a modern compiler: lexical analysis, parsing, abstract syntax, semantic actions, intermediate representations, instruction selection...
Fixed parsing of C++ rvalue references and improved parsing of decltypes. (case=20625) Fixed coloring of variables named "value." (case=37888) Fixed parsing of C++11 member initializations. (case=...
Perhaps because web service clients are usually written in dynamic languages these days, none of the existing C++ JSON parsers fitted my needs very well, so I wrote one that I used in another project....
This second edition of Grune and Jacobs’ brilliant work presents new developments and discoveries that have been made in the field. Parsing, also referred to as syntax analysis, has been and ...
数据集包括:ATR(human parsing)、LIP(Looking into Person)、Multi-human-parsing数据集。基本山涵盖了所有国际公开的human parsing数据集!
I fixed a bug in the handling of stringlist properties that affected the sort order and thus created a potential blind spot in the Find() mechanism. I enhanced the statement processing logic so that ...
- FIX: In "Windows ClearType" font rendering mode (OS Windows mode) the "garbage" pixels can appear from the right and from the bottom sides of the painted rectangle of the TFlexText object....