c++ - Namespaces confusion -
i new namespaces , trying c++ primer
#include<iostream> namespace jill { double bucket; double fetch; struct hill{ }; } double fetch; int main() { using namespace jill; hill thrill; double water = bucket; //double fetch; //<<<<<<<<<<<<// std::cin>> fetch; std::cin>> ::fetch; std::cin>> jill::fetch; std::cout<<"fetch "<<fetch; std::cout<<"::fetch "<< ::fetch; std::cout<<"jill::fetch "<< jill::fetch; } int foom() { jill::hill top; jill::hill crest; }
when line marked //<<<<<<<<<<<<//
not commented expected results. i.e. local
variable hides global
, jill::fetch
. when comment out, there 2 fetch left . global fetch
, jill::fetch
. , compiler gives error
namespacetrial1.cpp:17:13: error: reference ‘fetch’ ambiguous namespacetrial1.cpp:9:8: error: candidates are: double fetch namespacetrial1.cpp:5:9: error: double jill::fetch namespacetrial1.cpp:20:26: error: reference ‘fetch’ ambiguous namespacetrial1.cpp:9:8: error: candidates are: double fetch namespacetrial1.cpp:5:9: error: double jill::fetch
my question why the compiler confused lead ambiguity? why not assume fetch
jill::fetch
, since have added using namespace jill
@ start of main()
if use declarative using jill::fetch;
@ start of main, issue gets solved. because using jill::fetch
makes if has been declared @ location. so, there local fetch
variable. [am correct?] why using declaration
behave if variable declared @ location , using directive
doesnt?
the using directive modifies name lookup in way isn't intuitive programmers. standard says in [namespace.udir]p2:
during unqualified name lookup (3.4.1), names appear if declared in nearest enclosing namespace contains both using-directive , nominated namespace.
this wording means names namespace not appear in current scope, but in outer scope. in example using directive in function in global namespace, , jill in global namespace, names jill appears if in global namespace. (as joachim said, names aren't introduced there, don't conflict existing names , you ambiguous lookups when use them.)
this simple case , compiler gives error, good. can more complicated that.
namespace outer { namespace mid1 { int = 1; } namespace mid2 { namespace tricky { int = 2; namespace inner { void f() { using namespace mid1; std::cout << i; } } } } }
this output 2, not 1, though had using directive right next line referring i. nearest enclosing namespace contains both mid1
, using directive outer
, mid1::i
acts if declared in outer
. if had outer::i
shadowed tricky::i
, , mid1::i
fares no better.
an easy solution ban using directives , use using declarations , namespace aliases. they're far more intuitive.
Comments
Post a Comment