Using namespace doesn't work for definitions?

I'm having trouble understanding C ++ namespaces. Consider the following example:

//distr.h namespace bogus{ extern const int x; extern const int y; double made_up_distr(unsigned param); } 

Now, if I define my variables like cpp below everything compiles fine

 //distr.cpp #include "distr.h" #include <cmath> const int bogus::x = 10; const int bogus::y = 100; double bogus::made_up_distr(unsigned param){ auto pdf = (exp(param) / bogus::x) + bogus::y; return pdf; } 

But if I try to just enter the bogus namespace and use instead

 //broken distr.cpp #include "distr.h" #include <cmath> using namespace bogus; const int x = 10; const int y = 100; double made_up_distr(unsigned param){ auto pdf = (exp(param) / x) + y; return pdf; } 

My compiler tells me that the reference to x and y ambiguous. Why is this?

+4
source share
2 answers

There is a simple reason why this may not be believable to work the way you expected:

 namespace bogus { const int x; } namespace heinous { const int x; } using namespace bogus; using namespace heinous; const int x = 10; 

now if the x above refers to bogus::x , heinous::x or to the new global ::x ? This would be the third without using statements, which means that adding a using statement can significantly change the meaning of existing code.

The using statement is used to represent the contents of a region (usually, but not necessarily a namespace) for search. Statement

 const int x = 10; 

usually does not require a search in the first place, except to detect an ODR violation.

+6
source

Searching for a name for an identifier in declarations / definitions does not work the same as finding a name for use. In particular, this does not apply to the use of statements. There is a very simple reason for this: if it were otherwise, it would lead to various unpleasant surprises. Consider this:

 // sneakattack.h namespace sneakattack { void foo(); } using namespace sneakattack; // somefile.cpp #include "sneakattack.h" void foo() { std::cout << "Hello\n"; } // otherfile.cpp void foo(); int main() { foo(); } 

This program is currently working: the sneakattack::foo declaration is ignored, and the ::foo definition is correctly associated with use in another file. But if the search by name worked differently, somefile would suddenly identify sneakattack::foo , not ::foo , and the program would not be able to link.

+1
source

Source: https://habr.com/ru/post/1492730/


All Articles