Hi, The simplified code compiles correctly under GCC but not MSVC. why ? If I put Option struct in its own named namespace or remove the namespace Util, it compiles correclty. How can I make it work for both compilers ?
as far as I can tell VC is right at rejecting that code, because name lookup should ignore the globally defined vector<T> stream operators once those pulled in the Util namespace are found. I'm quite surprised gcc accepts it though ...
anyway, the solution is to either put the vector<T> stream operators in namespace std ( as it should be ) :
Hi, thanks very much. Both methods work. What I don't understand is that the overloaded IO operators of Option class have different types than the default ones,so why should there be a conflict ?
I edited my previous post and it works if I had a specialized IO operators for Int types even if it is placed in the same namespace.
not a good idea, now nobody will understand my answer above ...
Originally Posted by dshawul
What I don't understand is that the overloaded IO operators of Option class have different types than the default ones,so why should there be a conflict ?
you should not confuse overload resolution and name lookup. When the compiler finds an unqualified function name ( as in "f(x)" or in "x >> y" ) it first collects all name declarations filling a list of possible candidates and then and only then it applies the overloading resolution rules to find the best matching one ( provided some exists and is unique ).
Now, unqualified name lookup is performed by either traversing the declarative regions tree or via ADL ( = argument dependent lookup ). In the former case, the traversal stops when at least a name is found. In your original example that name was the operator>> in the Util namespace ( that borrows the names from the unnamed namespace where the Option struct injects its friend operators ). Hence, the compiler ignores the globally defined operator>>, giving you an error during overload resolution.
If you put those vector<T> operators in Util the compiler will consider them as candidates along with the Option operators, selecting the right one during overload.
If you put those vector<T> operators in the std namespace as I did above then ADL will include them in the candidate list ( this means that, among other things, the compiler will search also the namespace in which the types of the operator>> arguments reside, that for std::vector is exactly std ).
If you put Option ( and its operators ) in its own namespace as I did above then the name search will stop at global scope hence including your vector<T> operators.
Thanks a lot for the thorough explanation. Now I understand perfectly.
I have edited my original post with the source code that produces the error so that others understand
your explanation.
Thanks again.
Bookmarks