Possible to wrap or merge separate namespaces? - c++

I seem to recall seeing notes somewhere on a way to combine multiple namespaces into one.
Now, looking for said notes I am not finding them -- even searching using search terms combing, grouping, merging and wrapping I'm not coming up with anything. Maybe I misunderstood what I saw before. I don't have a specific application for this, it's just a curiosity and it's a bit contrived.
But, starting with two name spaces...
namespace a {int func() {return 1;}}
namespace b {int func() {return 2;}}
I was looking for syntax to either simply wrap them in another name -- after the fact --
(yes, I know I can rewrite it in a nested way) or merge them into one new space. But, I did find that I if I add to one of the namespaces that much works.
namespace c {namespace a{ int func2() {return 3;}} }
int main(int argc, char **argv)
{
int a = a::func(); // normal case
int c = c::a::func2(); // wrapped and added to
//int c = c::func2(); // doesn't work
//int d = a::func2(); // doesn't work
}
The question are:
1) is there syntax that just combines the two spaces into one new one?
2) is there a syntax to wrap the spaces without adding more to the subspaces?

You can do this:
namespace c
{
using namespace a;
using namespace b;
}
But if a and b have elements with the same names, you won't be able to use them from namespace c.

The best solution since C++11 is:
namespace c
{
inline namespace a { using namespace ::a; }
inline namespace b { using namespace ::b; }
}
This way for names that not conflict you can qualify only by c and you can resolve conflicts by qualifing c::a or c::b.
e.g.:
namespace a
{
auto foo_a() { cout << "a::foo_a" << endl; }
auto foo() { cout << "a::foo" << endl; }
}
namespace b
{
auto foo_b() { cout << "b::foo_b" << endl; }
auto foo() { cout << "b::foo" << endl; }
}
namespace c
{
inline namespace a { using namespace ::a; }
inline namespace b { using namespace ::b; }
}
int main()
{
c::foo_a();
c::foo_b();
c::a::foo();
c::b::foo();
return 0;
}

You can wrap the namespaces in a new one like this:
namespace c {
namespace a { using namespace ::a; }
namespace b { using namespace ::b; }
}

Related

How do namespace's with same name but different scope (e.g. foo, bar::foo) work?

If there are two namespaces named Foo and Bar and there is a namespace named Foo inside Bar. If I refer to a variable Foo::i from inside Bar will it search for i in both Foo and Bar::Foo. If not, is it possible to make the compiler search in both namespaces when i doesn't exist in Bar::Foo?
More concrentely in the below example, I am trying to refer variable i from namespace a in b without puting extra ::. I know putting :: works, I am trying to see if there is any other way to resolve this.
#include <iostream>
#include <string>
namespace a {
int i = 1;
}
namespace b {
namespace a {
}
namespace c {
int j = a::i; // Doesn't work, need to use ::a::i;
}
}
int main()
{
std::cout << b::c::j << "\n";
}
If you can change b::a, then you can indeed make certain declarations available in b::a from ::a as fallbacks:
namespace a {
int i = 1;
int j = 2;
}
namespace b {
namespace a {
namespace detail {
using ::a::i; // Selectively bring declarations from ::a here
}
using namespace detail; // Make the names in detail available for lookup (but not as declarations).
//int i = 2;
}
namespace c {
int j = a::i; // Uses ::a::i
// int k = a::j; // ERROR! We didn't bring ::a::j into b::a at all
}
}
Here it is live.
Un-commenting the declaration of b::a::i will change the output. Since a proper declaration takes precedence over names brought in by a namespace using directive.
You could explicitly have a using declaration in the inner namespace for variables that it wants to use from the outer one.
i.e. for your example,
namespace a {
int i = 1;
}
namespace b {
namespace a {
using ::a::i; //inner one does not define its own
int i2 = 2; //inner one creates its own variable
}
namespace c {
int j = a::i; // Doesn't work, need to use ::a::i;
}
}
See:
https://en.cppreference.com/w/cpp/language/namespace#Using-declarations

Is it possible to reuse variable names with using namespace?

For example, initially I have a sample program:
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
int a[3];
sort(begin(a),end(a));
cin;
}
Now I want to modifystd::cin(to provide more functions like invoke a function when input fails). So I introduces a headermystd.h like:
#include<iostream>
#include<algorithm>
//begin of mystd.h
namespace mystd {
struct cin_wrapper {
}cin;
}
//end of mystd.h
using namespace std;
int main() {
int a[3];
sort(begin(a),end(a));
mystd::cin;
}
But the change seems to be not convenient.(Users must mention all components using std::sort;using mystd::cin; or replace all cin with mystd::cin. using namespace std;using mystd::cin; causes the cin ambiguous)
In fact I'm going to write a modified standard library and make the use of it as convenient as the original one. The ideal code I wish users can write is:
(PS: this means mystd can be just used as std, not indicates I want to encourage users to use using namespace everywhere)
#include<iostream>
#include<algorithm>
#include "mystd.h"
using namespace mystd;
int main() {
int a[3];
sort(begin(a),end(a));//std::sort
cin;//mystd::cin
}
//or
int main() {
int a[3];
mystd::sort(mystd::begin(a),mystd::end(a));//sort, begin, end from std
mystd::cin;
}
I've tried to add using namespace std; in mystd but it also causes ambiguity.
One complicated solution I can image is to create a using statement like using std::string; in mystd for all std members not modified.
Is there a more practical way for me to implement mystd.h?
If you really insist on doing this, you can manage to do so by introducing your using statements at nested scopes. For example:
using namespace std;
int main() {
using namespace mystd;
int a[3];
sort(begin(a), end(a));//std::sort
cin_wrapper w;//mystd::cin
}
Anything involving using namespace std; should be avoided though (using other, more restricted namespaces isn't so bad, but that one is a huge truckload of cans of worms you're opening).
This isn't a good idea, because it is very fragile.
Imagine that someone writes your "ideal" code. Then, one day, you write mystd::sort that accepts a Range instead of two iterators.
Suddenly the meaning of the existing code has changed unexpectedly, and it starts to fail to compile because it wasn't anticipating that the number of parameters should now be one instead of two.
Your requirement is seamlesly implemented by the invention of "namespace".
If "productB" is your product with the same names as in "productA, you want to rewrite; then you decide, which names to be used by your users via some "using" statements in your interface file "productB.h" .
source file productA.h :
namespace productA
{
void f1();
void f2();
}
your source file productB.h : here you decide, what to use :
namespace productB
{
void f1();
void f2();
}
using productA::f1;
using productB::f2;
implementation:
#include <iostream> // std::cout
#include "productA.h"
#include "productB.h"
void productA::f1() { std::cout << "called A::f1" <<std::endl; }
void productA::f2() { std::cout << "called A::f2" <<std::endl; }
void productB::f1() { std::cout << "called B::f1" <<std::endl; }
void productB::f2() { std::cout << "called B::f2" <<std::endl; }
application: very convenient
#include "productA.h"
#include "productB.h"
int main () {
f1();
f2();
}
output:
called A::f1
called B::f2
notice: nothing is ambigous

A viable function with a default argument

The following example is given in N4296::13.3.3 [over.match.best]
namespace A
{
extern "C" void f(int = 5);
}
namespace B
{
extern "C" void f(int = 5);
}
using A::f;
using B::f;
void use()
{
f(3); // OK, default argument was not used for viability
f(); // Error: found default argument twice
}
I tried to write something similar:
#include <iostream>
namespace A
{
void foo(int a = 5){ std::cout << a << "1" << std::endl; }
}
namespace B
{
void foo(int a = 5){ std::cout << a << std::endl; }
}
using A::foo;
using B::foo;
int main()
{
foo(2); //Error
}
DEMO
But I got a compile-time error. Why does the Standard says that it's OK?
The difference is the extern "C", which affects namespace membership of the function:
From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1138.pdf
What remains is the definition of “same entity” with respect to ‘extern “C”’ language linkage? This is
addressed by 7.5¶6:
“At most one function with a particular name can have C language linkage. Two
declarations for a function with C language linkage with the same function name
(ignoring the namespace names that qualify it) that appear in different namespace scopes
refer to the same function. Two declarations for an object with C language linkage with
the same name (ignoring the namespace names that qualify it) that appear in different
namespace scopes refer to the same object.”
That's because the two functions are imported from their namespace, this means that the same function has 2 definitions, you can solve it like this:
#include <iostream>
namespace A
{
void foo(int a = 5){ std::cout << a << "1" << std::endl; }
}
namespace B
{
void foo(int a = 5){ std::cout << a << std::endl; }
}
int main()
{
A::foo(2);
B::foo(3);
}

Accessing member of an unnamed namespace when the outer namespace has a member with the same name

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

In C++, what is a "namespace alias"?

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