I have a quick question about namespace scope:
I have two namespaces, A and B, where B is nested inside A.
I declare some typedefs inside A.
I declare a class inside B ( which is inside A )
To access the typedefs (declared in A), from inside B, do I need to do "using namespace A;"
ie:
B.hpp:
using namespace A;
namespace A {
namespace B {
class MyClass {
typedeffed_int_from_A a;
};
}
}
This seems redundant... Is this correct?
To access the typedefs (declared in A), from inside B, do I need to do "using namespace A;"
No.
However if there is a typedef or some other symbol with same name as your typedef, defined in the namespace B, then you need to write this:
A::some_type a;
Lets do a simple experiment to understand this.
Consider this code: (must read the comments)
namespace A
{
typedef int some_type; //some_type is int
namespace B
{
typedef char* some_type; //here some_type is char*
struct X
{
some_type m; //what is the type of m? char* or int?
A::some_type n; //what is the type of n? char* or int?
};
void f(int) { cout << "f(int)" << endl; }
void f(char*) { cout << "f(char*)" << endl; }
}
}
int main() {
A::B::X x;
A::B::f(x.m);
A::B::f(x.n);
return 0;
}
Output:
f(char*)
f(int)
That proves that type of m is char* and type of n is int as expected or intended.
Online Demo : http://ideone.com/abXc8
No, you don't need a using directive; as B is nested inside of A, the contents of A are in scope when inside B.
Related
I have the following operators defined in the corresponding namespaces:
namespace literals
{
constexpr ID operator"" _ID(const unsigned long long dyngateID)
{
// ...
// return a constructed id
}
namespace multiplied
{
constexpr ID operator"" _ID(const unsigned long long dyngateID)
{
// ...
// return an id constructed in a specific way
}
} // namespace multiplied
} // namespace literals
In a .cpp file I would like to use both functions, hence I've declared using namespace literals and when I am declaring using namespace multiplied in a concrete function I am getting ambiguous call to overloaded function compile error. How can I differentiate these functions?
Test.cpp
using namespace literals;
void f()
{
// here I am using literals' _ID which is fine
const Type id{1_ID};
}
void g()
{
// here I want to use multiplied's _ID, but obviously I am failing to do so
using namespace multiplied;
const Type id{1_ID};
}
The name lookup rules for using namespace are such that the declarations introduced by it appear to be located in the inner-most namespace scope enclosing both the current namespace scope and the target namespace scope.
Therefore it is no good to disambiguate based on the scoping of multiple reachable using namespace statements.
Instead you can import the declaration with a using declaration:
void g()
{
using multiplied::operator""_ID;
const Type id{1_ID};
}
This will behave as if the operator was declared in the scope, so that name lookup will stop there and won't look at the declaration imported by the outer using namespace.
Alternatively, you can call the user-defined literal operator directly with a qualified call:
void g()
{
const Type id{multiplied::operator""_ID(1)};
}
As another possibility you can always limit the scope of the using namespace statements, so that only one of using namespace literals; or using namespace literals::multiplied; is reachable from any given scope using the operator, e.g.:
// no using namespace at this scope
void f()
{
using namespace literals;
const Type id{1_ID};
}
void g()
{
using namespace literals::multiplied;
const Type id{1_ID};
}
Consider the following code:
#include <iostream>
namespace one
{
int func(int num1, int num2)
{
return num1 * num2;
}
namespace two
{
int func(int num1, int num2)
{
return num1 * num2;
}
}
}
int f()
{
return one::two(1, 2) + 10;
}
int g()
{
return one::two::func(3, 4) + 10;
}
int main()
{
std::cout << f() << std::endl;
std::cout << g() << std::endl;
}
The above code will compile and run perfectly fine, and will work as expected, with f() using one::func() and g() using one::two::func(). If you have to write `using namespace one;' then you can do something like this:
using namespace one;
int f()
{
return func(1, 2) + 10;
}
int g()
{
return two::func(3, 4) + 10;
}
This will also result in the same output.
I'm beginning to learn C++. In the IDE codeblocks, this compiles:
#include <iostream>
using namespace std;
struct A {};
struct B {
A a;
}
void hi() {
cout << "hi" << endl;
}
int main() {
hi();
return 0;
}
But this doesn't:
struct B {
A a;
}
struct A {};
int main() {
hi();
return 0;
}
void hi() {
cout << "hi" << endl;
}
It gives me the errors:
error: 'A' does not name a type
error: 'hi' was not declared in this scope
Should class/function order matter in C++? I thought it doesn't. Please clarify the issue.
Yes, you must at least declare the class/function before you use/call it, even if the actual definition does not come until afterwards.
That is why you often declare the classes/functions in header files, then #include them at the top of your cpp file. Then you can use the classes/functions in any order, since they have already been effectively declared.
Note in your case you could have done this. (working example)
void hi(); // This function is now declared
struct A; // This type is now declared
struct B {
A* a; // we can now have a pointer to it
};
int main() {
hi();
return 0;
}
void hi() { // Even though the definition is afterwards
cout << "hi" << endl;
}
struct A {}; // now A has a definition
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.
I am trying to figure out if there's any known pattern/idiom in c++ for what I am trying to do here. Class A must be composed of an object that has a function whose argument must also be of type A. The following code doesn't compile since typeid may not be used in a constant expression. Any suggestions?
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
struct B {
int f(T& i) { cout << "Hello\n"; }
};
class A {
B<typeid(A)> b;
};
int main()
{
A k;
}
Your stated requirements don't need templates at all, just a forward declaration:
#include <iostream>
class A; // forward declare A
struct B {
int f(A &i); // declaration only, definition needs the complete type of A
};
class A {
B b;
};
int B::f(A &i) { std::cout << "Hello\n"; } // define f()
int main()
{
A k;
}
You are looking for B<A> b; The following program compiles without error or warning on g++ 4.4.3.
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
struct B {
int f(T& i) { cout << "Hello\n"; return 0; }
};
class A {
public:
B<A> b;
};
int main()
{
A k;
return k.b.f(k);
}
Note: If you are using templates only to avoid forward declaration, my solution is wrong. But, I'll leave it here in case you are using templates for some other legitimate reason.
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.