(c++)can u nest namespaces from extern sources - c++

i have a few headers with namespaces which all follow a certain namepattern
right now they all have a prefix infront of their actual name such as
namespace Xname{//inside name.h
//stuff here
};
namespace Xsomething{//inside something.h
//stuff here
};
now this works pretty good for my usage atm, but my idea is to create one more header that contains a namespace that would collect all the other namespaces so i can access them like so:
#include "mainheader.h"
X::name::stuff
X::something::stuff
this way i would just change the namespace name for new headers in the future like so
X::name::stuff
hello::name::stuff
i cant nest them like this:
namespace x{
namespace something{
//stuff
}
}

You could define the new namespaces inside each other like so
#include <iostream>
namespace Xname{//inside name.h
const int x = 0;
};
namespace Xsomething{//inside something.h
const int y = 1;
};
// Your other header
namespace X {
namespace name = Xname;
namespace something = Xsomething;
}
int main() {
std::cout << X::name::x << "\n";
std::cout << X::something::y << "\n";
}

If I understand you correctly, you can use the using namespace directive for this. Here is an example:
namespace Xname {
struct foo {};
}
namespace X {
namespace name {
using namespace Xname;
}
}
int main()
{
Xname::foo f1; // original
X::name::foo f2; // alternative
}

Related

Convenient way of 'using namespace' in implementation details (header only library)?

So i work on this library (header only) that has several modules and uses an inline namespace for versioning. Thus the fully qualified names can get a bit longer at times. I would like to use 'using namespace x' as an implementation detail inside the (inline) detail namespaces, but that pollutes the outer namespace.
See the example code on godbolt: https://godbolt.org/z/pdSXrs
I found two workarounds (see godbolt link) that do what I want, but seem to be overly complicated. Is there an easier way to do this? Should I just type out all the fully qualified names (and keep the error messages cleaner)? I would love to know what are the best practices for 'more complicated' namespace constructs.
Edit: added code as suggested
// think of these as in header files
namespace mylib{
namespace module0{
inline namespace mystuff{
// this constant conceptually belongs to module 0 but might be used as an
// implementation detail in other modules
int myconst = 42;
}
}
}
namespace mylib{
namespace module1{
// I would like to use this, but pollutes mylib::module1 namespace
inline namespace detail1{
using namespace mylib::module0::mystuff;
struct foo1{
int operator()(){
return myconst;
}
};
}
}
}
namespace mylib{
namespace module2{
inline namespace detail1{
// this works but seems overly complicated
namespace more_detail{
using namespace mylib::module0::mystuff;
struct foo2{
int operator()(){return myconst;}
};
}
// might be very cumbersome to use if lots of classes
using more_detail::foo2;
}
}
}
namespace mylib{
namespace module3{
inline namespace detail1{
// is this a good way to namespace a library...?
namespace more_detail{
using namespace mylib::module0::mystuff;
// not enough namespaces yet?!
namespace devil_of_details{
struct foo3{
int operator()(){return myconst;}
};
}
}
// useable for lots of classes/types in that namespace... but really?!
using namespace more_detail::devil_of_details;
}
}
}
// think of this as myprogram.cpp including the headers
#include <iostream>
int main(){
// polluted namespace. I can probably live with it, but it's not ideal
// constant should only be visible in module0
int x1 = mylib::module1::myconst;
std::cout << x1 << std::endl;
// ok
int x0 = mylib::module0::myconst;
// this is what I ideally want, i.e. not polluting module2 namespace
int x2_error = mylib::module2::myconst;
// this is what I ideally want, i.e. not polluting module3 namespace
int x3_error = mylib::module3::myconst;
// normal usage in cpp file
using namespace mylib::module2;
int x2 = foo2{}();
std::cout << x2 << std::endl;
// ok
using namespace mylib::module0;
std::cout << myconst << std::endl;
}
I would suggest namespace aliases.
namespace mylib{
namespace module1{
namespace details0 = module0::mystuff;
}
}
While this makes the other namespaces visible, it does not actually import the symbols the way a using does, that is mylib::module1 does not have a myconst member.
Also, note that so long as the namespace you are currently defining is part of mylib, there is no need to have mylib as part of the name. Even if you close mylib then re-open it.
That is:
namespace mylib {
namespace part1 { /* ... */ }
}
namespace mylib {
namespace part2 { namespace p1 = part1; }
}
p1 will refer to mylib::part1 so long as you don't specify that it is a fully-qualified name (::part1).

How to create a Class inside of a namespace?

What must the structure of a class look like if it is defined in a separate namespace?
Which parts belong in the header file and which in the cpp file?
How can I make the class accessible only through this specific namespace?
classname.h
#include <iostream>
namespace N {
class classname {
public:
void classmethod();
}
}
classname.cpp
#include "classname.h"
namespace N {
void classname::classmethod() {
std::cout << "classmethod" << std::endl;
}
}
main.cpp
#include "classname.h"
int main() {
N::classname a;
classname b; // Error!
a.classmethod();
return 0;
}

Variable Undefined In Namespace

I have the following set of files.
// HeaderOne.h
namespace foo
{
namespace bar
{
class A
{
.
.
.
};
}
}
// HeaderTwo.h
namespace foo
{
namespace bar
{
std::string const baz;
}
}
// HeaderTwo.cpp
#include "HeaderTwo.h"
using namespace foo::bar;
std::string const baz = "baz";
// HeaderOne.cpp
#include <iostream>
#include "HeaderOne.h"
#include "HeaderTwo.h"
using namespace foo::bar;
A::A()
{
std::cout << baz << std::endl;
}
I am using CMake as my build system and when I build, I get an undeclared identifier error on baz. I would think this should work, but any changes I make seem to still produce errors between definitions split among the files. Any ideas what might be going wrong here?
When you define something, use this form.
namespace name{
type definedname= value;
}
Or
type name::definedname= value;
Otherwise how could compiler know which namespace the definedname should be put under. It will put under no namespace.

How do I declare a namespace alias in a header file, then use it in a source file?

I want to put a namespace alias (ie namespace A = B::C) in a header file so I can use it in source files, but the compiler just tells me that its "not a namespace name". Any thoughts?
This is a very simplified axample of what I'm trying to do...
header file:
namespace A{
namespace B{
int getInt();
}
}
namespace AB = A::B;
source file:
#include "header_file.h"
#include <iostream>
int AB::getInt(){ // Error "AB is not a namespace name"
return 123;
}
You need to include the file that declares the namespace in the header file or as the comments say do this:
namespace B { namespace C { } }
namespace A = B::C;
At the point where you create the alias, the compiler must have already seen the aliased namespace.
Therefore, you must #include a file that contains said namespace or you must do this:
// "Forward Declaring" the namespace
namespace B { namespace C { } }
namespace A = B::C;

something about C++ unnamed namespace

#include <iostream>
namespace
{
int a=1;
}
int a=2,b=3;
int main(void)
{
std::cout<<::a<<::b;
return 0;
}
I complie it with my g++,but the output is 23,
who can explain it?
is that a way to get access to the <unnamed> namespace ::a?
:: in ::a refers to the global namespace. Anonymous namespace should be accessed via just a (or to be more specific, you shouldn't do like this at all)
No, you can't. You can work around it thus:
namespace
{
namespace xxx
{
int a = 1;
}
}
...
std::cout << xxx::a << ::b;
Using unnamed namespaces, this is not possible. Refer the below article
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/unnamed_namespaces.htm
You have to go for named namespaces.
You can access the global namespace, but don't redefine it.
#include <iostream>
namespace
{
int a=1;
}
int b=3;
int main(void)
{
std::cout<<::a<<::b;
return 0;
}
here the out is 13.