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
Related
Consider the following:
#include <iostream>
namespace X
{
void operator ""_test(unsigned long long x)
{
std::cout << x;
}
}
int main()
{
using namespace X;
10_test;
// 10_X::test; /* doesn't work */
}
I can refer to the user defined literal operator inside the namespace X by an explicit using namespace X;. Is there any way of referring to the literal operator without explicitly including the namespace? I tried the
10_X::test;
but of course doesn't work as the parser believes X refers to the name of the operator.
X::operator ""_test(10)
works but it's clumsy.
#include <iostream>
namespace X {
inline namespace literals {
void operator ""_test(unsigned long long x) {
std::cout << x;
}
}
}
int main() {
{
using namespace X::literals;
10_test;
}
{
using X::operator""_test;
10_test;
}
}
_test is both in X and X::literals. This permits people to using namespace X::literals; without pulling in everything from X, yet within X _test is also available.
Importing an individual literal is a bit annoying.
std does this with both std::chrono and std::literals and std::chrono::literals. inline namespaces let you define subsections of your namespace that you think people would want to import as a block without getting the rest of it.
If I create a namespace Maths and use another library with a namespace named Maths, will I get an error for re-declaring a variable like PI or re-defining a function like add?
I ask because if I choose to not use namespaces, I should get an error for doing those things, right?
If I don't get an error using namespaces but I do when not using namespaces, isn't safer to just not use namespaces?
Thanks for your time.
First thing, namespace must be global and In different namespace you can have same function or variable, but in same namespace you can't have same variable declaration twice.
namespace A {
int i=10;
char i ='a';/** is not valid **/
void print() {
...
}
}
namespace B {
float i = 1.5; /** valid **/
void print() { /** valid **/
...
}
}
In above example in namespace A and B you have i of int type and i of float type respectively which is valid but In namespace A itself you can't have variable i of different types (considered as re-declaration)
Decided to test it myself:
//in file testnamespace.h
namespace test
{
int t = 1;
void fooo(){};
}
//in file testnamespace2.h
namespace test
{
int t=10000;
void fooo(){int x = -2;}
}
//in file test.cpp
#include "testnamespace.h"
#include "testnamespace2.h"
int main()
{
int ayyyeee = test::t;
foo();
return 0;
}
This gives an error for redefinition,multiple initialization.
All I was looking for.
I have to define two functions, say, foo() and bar() in the same namespace and the same file. For the definition of the first, foo(), I want to use all symbols of, say, namespace other, but don't want symbols from namespace other to be automatically in scope for my other function, bar(). Is this possible? How?
(note: I don't want to know about alternative "solutions" either avoiding this problem of mitigating it, such as namespace o=other etc.)
Yes, it is possible:
void foo()
{
using namespace abc;
....
}
or
void foo()
{
using abc::x;
using abc::y;
using abc::z;
....
}
#include <iostream>
void quux() { std::cout << "root\n"; }
namespace other {
void quux(int x = 0) { std::cout << "other\n"; }
}
namespace taxes {
void foo() {
using namespace other;
quux(3);
};
void bar() {
quux();
}
}
int main() {
taxes::foo();
taxes::bar();
}
Live example
Note that quux in bar would be ambiguous if it could see other::quux, but it cannot.
On the other hand, this does not give you access to namespace other in the 'head' of the function foo (the parameters etc), but that is a rare requirement. There might be a solution involving inline namespaces or the like, but probably not worth the confusion.
I have listed my code below. I get soooo many errors saying cout and endl was not declared in this scope. I do not know what I am doing wrong or how to force the class to recognise cout? I hope I am explaining my problem correctly. If I comment out the methods (not the constructor) it works. I am probably just making a novice mistake here - please help.
using namespace std;
class SignatureDemo{
public:
SignatureDemo (int val):m_Val(val){}
void demo(int n){
cout<<++m_Val<<"\tdemo(int)"<<endl;
}
void demo(int n)const{
cout<<m_Val<<"\tdemo(int) const"<<endl;
}
void demo(short s){
cout<<++m_Val<<"\tdemo(short)"<<endl;
}
void demo(float f){
cout<<++m_Val<<"\tdemo(float)"<<endl;
}
void demo(float f) const{
cout<<m_Val<<"\tdemo(float) const"<<endl;
}
void demo(double d){
cout<<++m_Val<<"\tdemo(double)"<<endl;
}
private:
int m_Val;
};
int main()
{
SignatureDemo sd(5);
return 0;
}
The compiler needs to know where to find std::cout first. You just need to include the correct header file:
#include <iostream>
I'd suggest you not to pollute the namespace using using directives. Instead either learn to prefix std classes/objects with std:: or use specific using directives:
using std::cout;
using std::endl;
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; }
}