How and where using directive injects member names? - c++

AFAIK a using directive exposes or injects all the names of a namespace in the nearest enclosing namespace. and here is from C++ primer:
In contrast, a using directive makes the entire contents of a namespace available In general, a namespace might include definitions that cannot appear in a local scope. As a consequence, a using directive is treated as if it appeared in the nearest enclosing namespace scope.
In the simplest case, assume we have a namespace A and a function f, both
defined at global scope. If f has a using directive for A, then in f it will be as if the names in A appeared in the global scope prior to the definition of f
And from cppreference:
using-directive: From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name.
#include <iostream>
int x = 1;
int y = 2;
int z = 3;
namespace A{
namespace B{
int x = 5;
int y = 10;
int z = 0;
}
void foo(){
using namespace A::B;
std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are not ambiguous
}
}
namespace AA{
namespace BB{
void bar(){
using namespace A::B;
std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are ambiguous
}
}
}
int main(){
A::foo(); // works fine
AA::BB::bar(); // fails to compile
std::cout << "\ndone!\n";
}
Why the first version works fine (function A::foo()) but not the second version (AA::BB::bar())?
I find it a bit confusing 'injecting names into the nearest namespace that the using directive and the namespace definition'.

Yes, this is quite convoluted, but the quote you were giving explains exactly what's going on. In your first example (reduced number of variables to 1):
int x = 1;
namespace A {
namespace B {
int x = 5;
}
void foo(){
using namespace A::B;
std::cout << x << '\n';
}
}
The nearest namespace would be A. In essence, the code would be equivalent to
int x = 1;
namespace A {
int x = 5;
void foo(){
std::cout << x << '\n'; // x from NS a.
}
}
x would be a name defined in A and will be used.
In the second example,
namespace AA {
namespace BB {
void bar() {
using namespace A::B;
std::cout << x << '\n';
}
}
}
the nearest namespace would be global namespace. In essence, the code would be equivalent to
int x = 1;
int x = 5;
namespace AA {
namespace BB {
void bar() {
std::cout << x << '\n';
}
}
}
This code would be malformed, since x can't be redefined in the same scope.

Related

How to access the unnamed namespace with scope resolution?

I have this:
#include <iostream>
using namespace std;
// Variable created inside namespace
namespace first
{
int val = 500;
}
namespace
{
int val = 400;
}
// Global variable
//int val = 100;
int main()
{
// Local variable
int val = 200;
// These variables can be accessed from
// outside the namespace using the scope
// operator ::
cout << first::val << '\n';
cout << ::val << '\n';
cout << val << '\n';
return 0;
}
The ::val in this case will provide val = 400. But if I remove the comment to the global variable then the global namespace will be reached by ::val. So, in that case, how can I access the unnamed namespace?
int val = 400;
This is the output with
// Global variable
int val = 100; //Not commented.
500
100
200
A possible solution is to expand the unnamed namespace with a reference to the "hidden" variable:
#include <iostream>
// Variable created inside namespace
namespace first
{
int val = 500;
}
namespace
{
int val = 400;
}
// Global variable
int val = 100;
namespace {
int& access_to_val=val;
}
int main()
{
using namespace std;
// Local variable
int val = 200;
// These variables can be accessed from
// outside the namespace using the scope
// operator ::
cout << first::val << '\n';
cout << ::val << '\n';
cout << val << '\n';
cout << access_to_val << '\n';
return 0;
}
Check the code with Godbolt.
The output of the program is:
500
100
200
400
As a side remark: avoid using namespace std in the header.

IntelliSense: "count" is ambigous

#include "stdafx.h"
#include <iostream>
using namespace std;
void func(void);
static int count = 10; /* Global variable */
int main() {
while(count--) {
func();
}
return 0;
}
// Function definition
void func( void ) {
static int i = 5; // local static variable
i++;
cout << "i is " << i ;
cout << " and count is " << count << endl;
}
can't seem to fix this, just learning and reading Storage class in tutorialspoint.com . is this Visual Studio issue? because the code is working on Code::Blocks
There is a "count" function in std namespace, so it collides with you variable
You have several options:
1. Rename your variable to something else
2. Use "::count" instead of "count" (:: means global namespace and not std)
3. Don't do "using namespace std;", instead write "std::" in-front of everything that comes from std, for example: "std:cout", "std::endl"

How to access to anonymous namespace variable if the same variable exists in global

Let's imagine situation:
#include <iostream>
int d =34;
namespace
{
int d =45;
}
int main()
{
std::cout << ::d ;
return 0;
}
Here the output is 34, because :: means global namespace. But If I comment 3rd line the output is 45, which is strange.
If I use std::cout << d ; - I get error
s.cxx:12:15: error: reference to ‘d’ is ambiguous
How can I access unnamed_namespace::d in this scenario?
PS: I've read that unnamed namespace is used for static global variables aka visible only in file scope
You cannot disambiguate between the two ds in main without the aid of something else.
One way to disambiguate between the two is to create a reference variable in the namespace and then use the reference variable in main.
#include <iostream>
int d = 34;
namespace
{
int d = 45;
int& dref = d;
}
int main()
{
std::cout << dref << std::endl;
return 0;
}
But then, why confuse yourself with the same variable? If you have the option, use a different variable name in the namespace or give the namespace a name.
namespace
{
int dLocal = 45;
}
int main()
{
std::cout << dLocal << std::endl;
std::cout << d << std::endl;
return 0;
}
or
namespace main_detail
{
int d = 45;
}
int main()
{
std::cout << main_detail::d << std::endl;
std::cout << d << std::endl;
return 0;
}

Reference to ' ' is ambiguous

I am sorry but i don't know why this algorithm is not working.
The error at compiling is : "Reference to 'function' is ambiguous " and is on y = function() line, where I am calling the function
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.141
float function(int g, int m, int s, float z)
{
using namespace std;
z = (g + m/60.0 + s/3600.0)*PI/180.0;
return z;
}
int main()
{
using namespace std;
float y;
int g,m,s;
cout << "g = ";
cin >> g;
cout <<"m = ";
cin >> m;
cout<<"s= ";
cin >>s;
y = function();
cout << "y= " << y << endl;
//cout<< (g + m/60.0 + s/3600.0)*PI/180.0 << endl;
return 0;
}
Vers2 - updated:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.141
float function(int g, int m, int s)
{
//using namespace std;
float z = (g + m/60.0 + s/3600.0)*PI/180.0;
//std::cout << z <<std::endl;
return z;
}
int main()
{
// using namespace std;
float y;
int g,m,s;
std::cout << "g = ";
std::cin >> g;
std::cout <<"m = ";
std::cin >> m;
std::cout<<"s= ";
std::cin >>s;
function();
// std::cout << "y= " << y << std::endl;
//cout<< (g + m/60.0 + s/3600.0)*PI/180.0 << endl;
return 0;
}
There is a member function in std and you inserted it into your namespace. Avoid using using namespace std;; you can import what you need this way:
using std::cout;
using std::cin;
I am getting a similar type of error while I used "prev" as a global variable of Node* type. Just renaming it with "prevv" solved issue in my case.
It is mostly due to the name of a "variable or function" is present in some library you used.
I can't reproduce your error message (for any of your versions with 3 different compilers), but the basic problem with your code is that you apparently assume the g,m,s-variables in your main functions are automatically used as parameters when you call function() just because they happen to have the same name.
This is NOT the case!
The variables inside your main and in the parameter list of function() are completely independent entities. The proper way to call the function and passing the right values is this:
y=function(g,m,s);
This basically copies the values stored inside the main g,m,s variables into the g,m,s parameters, which are accessed inside the function and after the function has completed, it then copies the value stored inside the variable you "return" from the function (here z) into the variable y.
This should work whether you are using using namespace std; or not, as your function has a completely different signature, But I'd still highly recommend to choose another name for your function.
I hope this doesn't sound like an insult, but I highly recommend that you read a introductory book about c++ programming, as it seems you are missing out on basic concepts of the language.

can't use structure in global scope

I defined struct in the global scope, but when I try to use it, I get error: ‘co’ does not name a type, but when I do the same in a function, everything works fine
typedef struct {
int x;
int y;
char t;
} MyStruct;
MyStruct co;
co.x = 1;
co.y = 2;
co.t = 'a'; //compile error
void f() {
MyStruct co;
co.x = 1;
co.y = 2;
co.t = 'a';
cout << co.x << '\t' << co.y << '\t' << co.t << endl;
} //everything appears to work fine, no compile errors
Am I doing something wrong, or structures just cannot be used in global scope?
It's not that you "can't use structures in global scope". There is nothing special here about structures.
You simply cannot write procedural code such as assignments outside of a function body. This is the case with any object:
int x = 0;
x = 5; // ERROR!
int main() {}
Also, that backwards typedef nonsense is so last century (and not required in C++).
If you're trying to initialise your object, do this:
#include <iostream>
struct MyStruct
{
int x;
int y;
char t;
};
MyStruct co = { 1, 2, 'a' };
int main()
{
std::cout << co.x << '\t' << co.y << '\t' << co.t << std::endl;
}
Structure can be "used" as in "you can create a global variable of it".
The remainder of code, co.x = 1; and the rest can appear only inside functions.