Consider the following code.
namespace A::B::C::D::E {
struct X { };
}
namespace B {
using namespace A::B::C::D::E;
// or, using A::B::C::D::E::X;
// or, using X = A::B::C::D::E::X;
}
Let's say I use B::X incorrectly in some way and get an error. That error, in clang at least, will look something like
error: ... for type A::B::C::D::E::X.
I'd much rather have the error stated for B::X.
Is there a way to configure clang error messages to use the locations of using declarations, instead of the aliased entity?
I think it is good that the compiler uses A::B::C::D::E::X because otherwise it could be ambiguous. Like in the following example:
namespace A::B::C::D::E {
struct X {
int y;
};
}
namespace B {
using namespace A::B::C::D::E;
void foo() {
X aa;
B::X bb;
aa.y = 0;
}
struct X {
int z;
};
void bar() {
X aa;
B::X bb;
aa.y = 0;
}
}
int main() {
return 0;
}
There can be a struct X declared in the B namespace, and then that is B::X and it is necessary to call the other one A::B::C::D::E::X since otherwise they could not be distinguished.
Related
As far as I know, the declaration using namespace C; below in namespace D is essential for the compiler to complain about the ambiguity between the qualified-ids B::C::i and A::i in the code below, which is an example in the C++ Standard in [namespace.udir]/3:
namespace A {
int i;
namespace B {
namespace C {
int i;
}
using namespace A::B::C;
void f1() {
i = 5; // OK, C::i visible in B and hides A::i
}
}
namespace D {
using namespace B;
//using namespace C;
void f2() {
i = 5; // ambiguous, B::C::i or A::i?
}
}
void f3() {
i = 5; // uses A::i
}
}
void f4() {
i = 5; // ill-formed; neither i is visible
}
Surprisingly, all three compilers VS2017, GCC and clang show the same error message when the declaration using namespace C; is commented out of the code. What am I missing?
main.cpp:17:13: error: reference to 'i' is ambiguous
i = 5; // ambiguous, B::C::i or A::i?
The ambiguity is on account of the earlier using directives:
namespace B {
// ...
using namespace A::B::C;
// ...
}
namespace D {
using namespace B;
Since using directives are transitive for unqualified lookup ([namespace.udir]/4).
I have seen this used in various places. C++ programmers will often use the :: operator right before a global function call.
e.g
::glGenBuffers( 1, &id );
Why is this? Why not just use:
glGenBuffers( 1, &id );
To avoid accidental namespace clashing. For example if you current namespace would have glGenBuffers which does something different from the "good" glGenBuffers with :: you can specify to call the glGenBuffers which is in the global namespace.
The problem is 1) names in inner scopes hide names in outer scopes and 2) there can be ambiguous of function calls when using directive is used.
For example (ambiguity)
#include <algorithm>
using namespace std;
void swap( int &x, int &y )
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int x = 5, y = 10;
//swap( x, y ); compiler error: what function to call?
::swap( x, y ); // the user defined function is called
std::swap( x, y ); // the standard function is called.
}
Another example of hidding names
#include <iostream>
void f() { std::cout << "::f()\n"; }
namespace MyNamespace
{
void f() { std::cout << "MyNamespace::f()\n"; }
void g() { f(); } // calls MyNamespace::f()
void h() { ::f(); } // calls ::f()
}
int main()
{
MyNamespace::g();
MyNamespace::h();
}
As you can see here C++ Scope Resolution Operator ::
The :: (scope resolution) operator is used to qualify hidden names so
that you can still use them. You can use the unary scope operator if a
namespace scope or global scope name is hidden by an explicit
declaration of the same name in a block or class.
::glGenBuffers to force choose the method in global namespace
void method()
{
std::cout << "method in global namespace";
}
class Test {
void method()
{
std::cout << "method in Test class";
}
void test()
{
method(); // method in Test class
::method(); //method in global namespace
}
}
Explicitly marking the scope may save you from unexpected matches through using declarations or argument dependent lookup. For example, consider the following:
namespace foo
{
class X {};
void bar(X*, int):
}
// ... much in between ...
foo::X some_object
// ... more in between ...
void bar(X*, long);
int main()
{
bar(&some_object, 42); // calls foo::bar, because it is a better match
::bar(&some_object, 42); // calls ::bar, because it is explicitly told to
}
If you were not aware that there is a bar in namespace foo, or that some_object has a type from namespace foo, the call to foo::bar instead of ::bar may catch you by surprise.
The scope operator (::) is used for accessing the global namespace on 2 occasions mainly:
a) importing a global method / variable / typedef (from global namespace) into a namespace:
int fun()
{
return 1;
}
namespace x
{
using ::fun;
// you cannot do `using fun`, as using requires a namespace after
// in this case, we are `using` the global namespace
}
int main()
{
std::cout << fun() + x::fun(); // prints 2
}
Edit: This is done by some STL implementations, for example: std::size_t:
typedef unsigned int size_t;
namespace std
{
using ::size_t;
}
size_t x = 1;
std::size_t y = 2;
b) To avoid clashing:
# include <algorithm>
using namespace std;
template<class T> inline
void swap(T &left, T &right)
{
T tmp = left;
left = right;
right = tmp;
}
int main()
{
int a = 1, b = 2;
// swap(a, b) - error: which 'swap'?
std::swap(a, b); // the one in <algorithm>
::swap(a, b); // the one i defined
}
Note: using namespace std; is not a reccomended practise.
Edit
MSVC compiler provides the _CSTD macro (#define _CSTD ::), so that you can use using _CSTD fun;, e.t.c instead if you prefer.
Here is the test code
extern "C" {int printf(const char *, ...);}
namespace PS
{
int x = 10; // A
// some more code
namespace {
int x = 20; // B
}
// more code
}
int main()
{
printf("%d", PS::x); // prints 10
}
Is there any way to access inner(unnamed) namespace's x inside main?
I dont want to change code inside PS. Apologies if the code looks highly impractical.
P.S: I tend to use the name x quite often.
No. The only way to specify a namespace is by name, and the inner namespace has no name.
Assuming you can't rename either variable, you could reopen the inner namespace and add a differently-named accessor function or reference:
namespace PS {
namespace {
int & inner_x = x;
}
}
printf("%d", PS::inner_x);
One way is to add this code:
namespace PS
{
namespace
{
namespace access
{
int &xref = x;
}
}
}
and then you can access what you want:
std::cout << PS::access::xref << std::endl; //prints 20!
Demo : http://ideone.com/peqEs
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do you import an enum into a different namespace in C++?
How can following enum namespace problem been solved?
namespace A {
typedef enum ABar { a, b };
void foo( ABar xx ) {}
}
namespace B {
typedef enum A::ABar BBar;
void foo( BBar xx ) { A::foo( xx ); }
}
int main() {
B::foo( B::a ); // 'a' : is not a member of 'B'
// 'a' : undeclared identifier
}
While you typedef a type, you don't import the symbols defined in that namespace. So while you can write:
int main() {
B::BBar enumVariable=A::a;
}
you cannot access B::a as this symbol does not exist.
A partial walkaround and, in my opinion, a way to make the code more clean, although also a bit more longer to write, is to pack every enum into its own struct, e.g.:
struct ABar {
enum Type {a, b};
};
typedef ABar BBar;
int main() {
ABar::Type var=ABar::a;
BBar::Type var2=BBar::a;
}
You will be able to, if you still need it, to pack ABar into a namespace and normally typedef in another namespace too.
The problem is that the declaration of an enum does not only create the type, but it also declares the enumerated identifiers with the given values. When you do a typedef you are only creating a local alias to the type, but the values are not brought to the new namespace. That is, the compiler will see B::BBar and it will know by means of the typedef that you are referring to A::ABar. But while processing the B::a, there is nothing in B namespace that refers to that.
For that to work, you would have to also bring a and b into the new namespace, and that is not done by the typedef, as they are not types. Anyway it is achievable like:
namespace A {
enum ABar {
a, b
};
}
namespace B {
typedef ::A::ABar BBar;
using ::A::a;
using ::A::b;
}
I would not recommend doing it, as it will become a maintenance problem quite rapidly (you will have to remember to update both namespaces with each change to the original one.
As to how to deal with the problem, the workaround proposed by #CygnusX1 is actually a good option, and if you are using a C++0x compiler the language allows for a similar idiom as it allows to access the enumerated values through the enum type:
namespace A {
enum ABar { a,b };
}
namespace B {
typedef A::ABar BBar;
}
int main() {
std::cout << B::BBar::a << std::endl; // extra enum qualification
}
You can not typedef an enum. You can use it :
namespace B {
using A::ABar;
}
EDIT
Here is modified example, that works :
namespace A {
enum ABar { a, b };
void foo( ABar xx ) {}
}
namespace B {
using A::ABar; // 'ABar' : is injected into namespace 'B'
using A::a; // 'a' : is injected into namespace 'B'
void foo( ABar xx ) { A::foo( xx ); }
}
int main() {
B::foo( B::a );
}
However, as CygnusX1 and David pointed out, the above is polluting the namespace B, and it is better to do it like this :
namespace A {
enum ABar { a, b };
void foo( ABar xx ) {}
}
namespace B {
void foo( A::ABar xx ) { A::foo( xx ); }
}
int main() {
B::foo( A::a );
}
There is also a third option, to typedef it, but properly:
namespace B {
typedef A::ABar BBar;
void foo( BBar xx ) { A::foo( xx ); }
}
but you still can not do this:
B::foo( B::a ); // 'a' : is not a member of 'B'
// 'a' : undeclared identifier
because BBar is just an alias of A::ABar.
What is a "namespace alias" in C++? How is it used?
A namespace alias is a convenient way of referring to a long namespace name by a different, shorter name.
As an example, say you wanted to use the numeric vectors from Boost's uBLAS without a using namespace directive. Stating the full namespace every time is cumbersome:
boost::numeric::ublas::vector<double> v;
Instead, you can define an alias for boost::numeric::ublas -- say we want to abbreviate this to just ublas:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
Quite simply, the #define won't work.
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
Compiles fine. Lets you work around namespace/class name collisions.
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
On the last line, "Hmm:Oops" is a compile error. The pre-processor changes it to Nope::Oops, but Nope is already a class name.
More on this topic http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
It is all about choosing an alias for a looong namespace name, such as:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Then later, you can typedef
typedef SHORT::mytype
instead of
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
This syntax only works for namespaces, cannot include classes, types after the namespace NAME =
Also note that namespace aliases and using directives are resolved at compile time, not run time. (More specifically, they're both tools used to tell the compiler where else to look when resolving names, if it can't find a particular symbol in the current scope or any of its parent scopes.) For example, neither of these will compile:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
Now, a curious mind may have noticed that constexpr variables are also used at compile time, and wonder whether they can be used in conjunction with either an alias or a directive. To my knowledge, they cannot, although I may be wrong about this. If you need to work with identically-named variables in different namespaces, and choose between them dynamically, you would have to use references or pointers.
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
The usefulness of the above may be limited, but it should serve the purpose.
(My apologies for any typoes I may have missed in the above.)
Namespace is used to prevent name conflicts.
For example:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
You now have two classes name bar, that are completely different and separate thanks to the namespacing.
The "using namespace" you show is so that you don't have to specify the namespace to use classes within that namespace. ie std::string becomes string.
my resource: https://www.quora.com/What-is-namespace-in-C++-1