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.
Related
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
}
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).
//SomeStruct.h
namespace SomeNameSpace
{
typedef struct SomeStruct
{
int SomeVariable;
} SomeStruct, *PSomeStruct;
}
and
//Function.h
namespace SomeNameSpace
{
Function( SomeStruct smStr );
}
then
//Function.cpp
#include "some_path_with_both_headers.h"
void SomeNameSpace::Function( SomeStruct smStr )
{
...
}
instead of
//Function.cpp
#include "some_path_with_both_headers.h"
void SomeNameSpace::Function( SomeNameSpace::SomeStruct smStr )
{
...
}
so that the parameter is the struct in namespace SomeNameSpace. The first Function.cpp is the correct syntax?
You could also do this:
//Function.cpp
#include "some_path_with_both_headers.h"
namespace SomeNameSpace
{
void Function( SomeStruct smStr )
{
...
}
}
You can use both versions, the latter is more verbose.
The compiler already knows about the namespace of Function and now encounters a type it doesn't know. So it starts its search in the same namespace and finds SomeStruct, everything is okay. If it wouldn't find it there it would go higher up the namespace tree until it reaches the global namespace.
This is called argument-dependent lookup (ADL) and doesn't only apply to namespaces but to classes as well.
I would like to avoid re-definition from two different include files as follows:
File ABC.h
extern int v=1;
File foo.h
#include "ABC.h"
class Foo
#ifdef BLA
: public ABC
#endif
{
...
};
File bar.h
extern int v=3;
Main:
#define BLA
#include <foo.h>
#include <bar.h>
Basically foo is a class written by me, and bar is a third-party library. But it doesn't seem to work. How should I solve the problem?
Sorry, it's a bit hard to describe, the example is kind of bad as the conflicted parts are actually not variables, but something like #define and wrapped in big blocks of code (error message is: "multiple definition of `__vector_17'"). Is there a way to solve it without using a namespace?
Using a namespace you can solve this problem:
namespace foo
{
int val =1;
}
namespace bar
{
int val =3;
}
using namespace foo;
int x = val; //Now x will be assigned with 1
A namespace is what you need:
namespace foo
{
int v =100;
}
namespace bar
{
int v =500;
}
if I define a namespace log somewhere and make it accessible in the global scope, this will clash with double log(double) from the standard cmath header. Actually, most compilers seem to go along with it -- most versions of SunCC, MSVC, GCC -- but GCC 4.1.2 doesn't.
Unfortunately, there seems no way to resolve the ambiguity, as using declarations are not legal for namespace identifiers. Do you know any way I could write log::Log in the global namespace even if cmath is included?
Thanks.
EDIT: Would anybody know what the C++03 standard has to say about this? I would have thought that the scope operator sufficiently disambiguates the use of log in the code example below.
#include <cmath>
namespace foo
{
namespace log
{
struct Log { };
} // namespace log
} // namespace foo
using namespace foo;
int main()
{
log::Log x;
return 0;
}
// g++ (GCC) 4.1.2 20070115 (SUSE Linux)
// log.cpp: In function `int main()':
// log.cpp:20: error: reference to `log' is ambiguous
// /usr/include/bits/mathcalls.h:110: error: candidates are: double log(double)
// log.cpp:7: error: namespace foo::log { }
// log.cpp:20: error: expected `;' before `x'
I'd suggest:
foo::log::Log x; // Your logging class
::log(0.0); // Log function
Generally I wouldn't write using namespace foo; as there is no point having it in the foo namespace if you're not going to use it and it pollutes the global namespace.
See this related question:
How do you properly use namespaces in C++?
Although it does not help you, the error from GCC 4.1.2 is incorrect. The log in log::Log can only refer to a class or namespace name.
If your code also needs to compile with GCC 4.1.2, then there are two options:
Use the fully qualified name foo::log::Log
Use a namespace alias:
namespace log1 = foo::log;
log1::Log logger;
cmath uses ::log for some reason to get it from the global scope and can't decide between the function and your namespace.
Namespaces keep code contained to prevent confusion and pollution of function signatures.
Here's a complete and documented demo of proper namespace usage:
#include <iostream>
#include <cmath> // Uses ::log, which would be the log() here if it were not in a namespace, see https://stackoverflow.com/questions/11892976/why-is-my-log-in-the-std-namespace
// Silently overrides std::log
//double log(double d) { return 420; }
namespace uniquename {
using namespace std; // So we don't have to waste space on std:: when not needed.
double log(double d) {
return 42;
}
int main() {
cout << "Our log: " << log(4.2) << endl;
cout << "Standard log: " << std::log(4.2);
return 0;
}
}
// Global wrapper for our contained code.
int main() {
return uniquename::main();
}
Output:
Our log: 42
Standard log: 1.43508
In c++0x or c++11, the following should work, compile with -std=c++0x or -std=c++11:
#include <iostream>
#include <math.h>
namespace ___ {
namespace log {
void init() {
std::cout << "log::init()" << std::endl;
}
} // namespace log
} // namespace ___
using namespace ___;
int main() {
log::init();
std::cout << ::log(3.2) << std::endl;
return 0;
}