This is an area I have never known since I learned C ++. Recently I want to review the basic knowledge of C ++, so I am reading a book. I think this part about name search is novel in this book. I will summarize it a little.
What is name search?
In my opinion, it should be like this. For example, if you call a function, how does the compiler look for the definition of this function. This is the so-called name search process. First, write a program to check the running process of this name search !!!
# Include <iostream> <br/> # include <string> <br/> # include <vector> <br/> # include <iterator> <br/> # include <Algorithm> <br/> namespace test <br/> {<br/> Class A <br/>{< br/> public: <br/> A (): Str _ ("") <br/>{< br/>}< br/> A (STD: String Str ): STR _ (STR) <br/>{< br/>}< br/> void setstr (STD: String const & Str) <br/>{< br/> This-> STR _ = STR; <br/>}</P> <p> STD: String getstr () const <br/>{< br/> return this-> STR _; <br/>}< br/> PRIVATE: <br/> STD: String STR _; <br/>}; <br/>}< br/> STD: istream & operator> (STD: istream & in, test: A & thiz) <br/>{< br/> STD: String str_tmp; <br/> If (in> str_tmp) <br/>{< br/> thiz. setstr (str_tmp); <br/>}< br/> else <br/>{< br/> thiz. setstr ("wrong"); <br/>}< br/> return in; <br/>}< br/> STD: ostream & operator <(STD :: ostream & out, test: a const & thiz) <br/>{< br/> out <thiz. getstr () <STD: Endl; <br/> return out; <br/>}< br/> int main () <br/>{< br/> using namespace test; <br/> using namespace STD; <br/> vector <A> token; <br/> copy (istream_iterator <A> (CIN), istream_iterator <A> (), back_inserter (token); <br/> copy (token. begin (), Token. end (), ostream_iterator <A> (cout, ""); <br/> return 0; <br/>}
The Class A of this program is defined in namespace test, and the <> operators are defined in the global scope.
Many inexplicable errors, the most important one is:
"Error: no match for 'operator> 'in' * (STD: istream_iterator <test: A> *) This)-> STD: istream_iterator <test :: A >::_ m_stream >>( (STD: istream_iterator <test: A> *) This)-> STD: istream_iterator <test: A> :: _ m_value'
"
It can be understood as not matching> the meaning of this function. This is the question. Why can't I recognize the stream operators I have defined, but I cannot find a matching function.
This is the name search function in the C ++ compiler.
There are two methods to search for C ++ names:
One is an ol (ordinary Name Lookup) common search rule.
One is ADL (argument-depentment lookup) dependent on the real Parameter Name Lookup.
These two search rules are the C ++ Search rules. If these two rules are still not found, the compiler will report errors such as no matching function. The ol rule starts from the adjacent scope. If it is not found, it goes to a larger scope for search, ol has such a rule (OL terminates as soon as the name is found), that is, when the compiler finds the same name as the function to be searched in this scope, this will no longer be found in a larger scope. That is to say, it stops at this place. If there is an overload problem, the compiler will consider the function in the scope it finds. Which function is the most matched, but it will not look for the outer layer. This may cause errors.
The meaning of the ADL rule is similar to that of the word surface. The compiler searches for the function definition or name based on the type of the real parameter. If it is a class, it may include its own names and spaces of all its base classes. If it is a template class, that is to define the namespace of the prototype template and the namespace of all the real parameters of the template.
After analyzing the process of searching the above program name, copy1 (the first call of copy) will call> This operator, and the compiler will regard it as a member function of istream, then, find the name of the function in the istream class. However, because istream only reloads the specified data type, it is not the best match, however, the compiler still finds this name in the scope of the class, so it will not go global.
However, when the compiler uses the ADL rule, it only finds the namespace STD and test, but our custom stream operator is defined in the global scope, so an error will be reported.
If you include the defined <> in test, you can compile and run it.
Therefore, it is very important to place the Declaration and main types of operators in the same namespace. Otherwise, the compiler cannot find their ....