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.
Related
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.
#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"
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;
}
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.
#include <iostream>
#include <string>
using namespace std;
string a;
namespace myNamespace
{
string a;
void output()
{
cout << a << endl;
}
}
int main()
{
a = "Namespaces, meh.";
myNamespace::a = "Namespaces are great!";
myNamespace::output();
}
The result is "Namespaces are great!". So is there any way to access the global string a inside of the namespace myNamespace instead of just the local one?
Like this:
void output()
{
cout << ::a << endl; //using :: = the global namespace
}