Namespace questions: forward declaration and mixing namespaces - c++

I'm not very familiar with C++, and this is my first time working with more than just the namespace std. What is the difference between the following?
using MyNameSpace::MyClass;
vs
namespace MyNameSpace {class MyClass;}
After both, it seems I can now create a MyClass object. Is one way better than the other? Also, if I don't do either, can I still reference MyClass by appending MyNameSpace::MyClass before it every time I need to?
Next, if I forward declare using the second option, do I still need to #include "MyClass.h"? In my (not very good) understanding, in C++, you make header files in order to forward declare classes so that they can be used later. So if you have already forward declared, would you still need to include the header file?
Finally, when working with multiple namespaces (namespace Architecture and namespace Router), I have an error I don't know how to explain. In one of my header files, I have using std::vector as the first line after my #include statements. This statement is not within any namespace, I think. When compiling, I receive the error, "'Architecture::std::vector' has not been declared". To remedy this, I can change the statement to using ::std::vector to tell it to look at global scope for std::vector.
However, I don't understand why this problem exists. Since I am declaring using std::vector at the top of my header file, why am I not already at global scope? A better question might be: how can I tell which scope I am in at the top of a header file? Additionally, I thought in C++ (and according to this answer What is the difference between writing "::namespace::identifier" and "namespace::identifier"?), if you couldn't find the name within the current scope, you would automatically look up a level until you reach global scope.
I hope these questions are well written and understandable. Hopefully I can get some answers to these questions and begin to understand how namespaces interact with one another.

using MyNameSpace::MyClass;
This using-declaration injects the name MyClass into the current scope, referring to the entity denoted by MyNameSpace::MyClass, which must have been previously declared.
namespace MyNameSpace {class MyClass;}
This is a forward declaration of the class MyClass in the namespace MyNamespace.
After both, it seems I can now create a MyClass object.
Unlikely in the second case, unless you have a using namespace MyNamespace; and the full definition of MyClass is available.
Is one way better than the other?
They do completely different things.
Also, if I don't do either, can I still reference MyClass by appending MyNameSpace::MyClass before it every time I need to?
If using MyNameSpace::MyClass; compiles (i.e., MyNameSpace::MyClass has been declared), then you can do this. Otherwise, you can't.
Next, if I forward declare using the second option, do I still need to
#include "MyClass.h"? In my (not very good) understanding, in C++,
you make header files in order to forward declare classes so that they
can be used later. So if you have already forward declared, would you
still need to include the header file?
Headers usually carry the full class definition - which includes declarations of all its data members and member functions. A forward declaration like class MyClass; will not allow you to create a MyClass object, since the compiler would not know how much memory to allocate for that object or what constructors are available.
However, I don't understand why this problem exists. Since I am
declaring using std::vector at the top of my header file, why am I not
already at global scope? A better question might be: how can I tell
which scope I am in at the top of a header file? Additionally, I
thought in C++ (and according to this answer What is the difference
between writing "::namespace::identifier" and
"namespace::identifier"?, if you couldn't find the name within the
current scope, you would automatically look up a level until you reach
global scope.
This sounds like a problem of missing braces. If a header you wrote did not close namespace Architecture, then anything you include after that header will be put into the Architecture namespace by accident. If that's not the problem, please post a MCVE.

Related

Using namespaces and includes

The question might be trivial (and possibly a duplicate).
As far as I understand, a C/C++ header file (with a using namespace in it), when used by other source files, it is copied right at the point where the #include directive was in that source file.
Also, given that a source file uses a relatively large number of include directives and that there may be a couple of "redefinitions" for the entire standard library (simply targeted at different implementations).
Here is the main question: How do I know which namespaces am I currently using at any point in the source file if the source file has no using namespace statement?
I'm reading through source files and I have no idea which namespace is being used.
One can override the namespace cleverness by using something like ::std::getline().
If there is no easy way of determining the namespace, is it fair to refactor those files, such that where say string is used to replace it with ::std::string?
If you don't have a using namespace ... directive you're not using any namespace. In general, your code should refer to things in the standard library with their full names, e.g., std::cout, std::get_line(), std::string.
Yes, you can save your self some typing at the expense of loss of clarity and sometimes mysterious compilation failures or, worse, runtime failures with using namespace std;. After that, you don't have to put std:: in front of the names of things in the standard library: cout, get_line(), string. The using directive puts those names into the global namespace, along with a bunch of sludge that you probably aren't interested in.
If you use something like using namespace std; it should appear only in a source file, never in a header. That way you can tell which namespaces have been "used" by looking at the top of the file. You shouldn't have to track through all your headers for stray using directives.
using namespace does not mean that you currently use this specific namespace. It means, that all types, variables and functions from this namespace are now in your global namespace, for this translation unit. So, you might have multiple of these statements.
This is why header files should never use using namespace. There is no easier way than using std::string within a header file, you should always be very explicit about the namespace without using namespaces.
Having used using namespace xxx, there is no way of finding out that xxx is now in global namespace, I am afraid.
using namespace does not do what you expect...
If you want to place functions, classes or variables in a namespace, you do it this way:
namespace foo
{
void f();
}
namespace bar
{
void f();
}
This declares two functions f in namespaces foo and bar respectively. The same you will find in header files; if there is no namespace specified as above, then the function/class/variable is in global namespace. Nothing more.
using namespace now allows you to use functions from a namespace without having to specify it explicitly:
// without:
foo::f();
bar::f();
f(); // unknown!
using namespace foo;
foo::f(); // still fine...
bar::f();
f(); // now you call foo::f
Be aware that this is bad practice, though (the link refers to namespace std, but same applies for all namespaces).
This is even worse in header files: there is no way to undo the effect of a declared using namespace <whatever> again – so you impose it on all users of your header, possibly causing great trouble to some of them. So please don't ever use it in header files.
There are three approaches I can think of right now:
Use the IDE: A modern development environment should be able (possibly with the help of plug-ins) to analyze your code while you edit, and tell you the authoritative qualified name of any identifier you hover the mouse cursor over.
Of course this is not an option if you are not using an IDE, and sometimes even IDEs may get confused and give you wrong information.
Use the compiler and guesswork: If you already have a hunch which namespace you might be in, you can define some object, reference it via qualified name, and see if the code compiles, like so:
const int Fnord = 1;
const int* Probe = &::solid::guess::Fnord;
One caveat is that it may give misleading results if using namespace or anonymous namespaces are involved.
Use the preprocessor: Most compilers define a preprocessor macro that tells you the name of the function it is used in, which may include the namespace; for example, on MSVC, __FUNCTION__ will do just this. If the file contains a function that you know will be executed, you can have that function tell you its authoritative qualified name at run-time, like so:
int SomeFunction(void)
{
printf("%s\n", __FUNCTION__);
}
If you can't use standard output, you might store the value in a variable and use a debugger to inspect it.
If you can find no such function, try defining a class with a static instance of itself, and placing the code in the constructor.
(Unfortunately I can't think of a way to inspect the macro's value at compile-time; static_assert came to my mind, but it can't be used inside functions, and __FUNCTION__ can't be used outside.)
The macro is not standardized though, and may not include the namespace (or it may not exist at all). On GCC for instance, __FUNCTION__ will only give you the unqualified name, and you will have to use __PRETTY_FUNCTION__ instead.
(As of C99 and C++11 there does exist a standardized alternative, __func__, but the format of the function name is unspecified, and may or may not include the namespace. On GCC it does not.)

How can I `unuse` a class?

In our huge codebase, in one of the include files, we have the statement
using std::some_function
However, I want to "unuse" some_function and use another some_function. I cannot modify this header because most of the code base depends on it.
Is there a possibility to do so?
I don't think there is. You should place your function in a namespace and qualify its use:
namespace MyNamespace
{
void some_function();
}
//...
MyNamespace::some_function();
Of course, the best you can do is remove the using directive and fix the code - but I (sadly) do understand why this isn't always an option.
EDIT: Just maybe, the using directive isn't there because of lazyness, but someone actually wants you to think twice before implementing your own some_function.
Depends what you want the scope of the "unuse" to be.
If it's scoped (to your own namespace or even better to a function) then you can put using MyNamespace::some_function; in your scope.
If it's global scope then the author of the original header has overruled you - in effect they got to the name ::some_function first, and they've prevented you from usingit for anything else. They shouldn't have pulled a std function into the global namespace, but you just have to live with their error.
Assuming that you don't want to make the same mistake they made, you only want the "unuse" to apply to one source file, you're not putting it in global scope in a header yourself. In that case you could #define some_function MyNamespace::some_function, but I don't recommend it because readers/maintainers of the code won't expect to have to realise that a lower-case name is actually a macro.
If some_function is a function (not a class as in the title), and you're only dealing with one overload (for example void some_function(), then there's another ugly workaround. Add another parameter:
static void some_function(int) { MyNamespace::some_function(); }
Then you can call it as some_function(0) and get the MyNamespace version. But if you're going to type extra text (in this case 0) I should think you might as well do it the expected way: make that extra text be MyNamespace::, or just use a different name.

"using namespace" in c++ headers [duplicate]

This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 1 year ago.
In all our c++ courses, all the teachers always put using namespace std; right after the #includes in their .h files. This seems to me to be dangerous since then by including that header in another program I will get the namespace imported into my program, maybe without realizing, intending or wanting it (header inclusion can be very deeply nested).
So my question is double: Am I right that using namespace should not be used in header files, and/or is there some way to undo it, something like:
//header.h
using namespace std {
.
.
.
}
One more question along the same lines: Should a header file #include all the headers that it's corresponding .cpp file needs, only those that are needed for the header definitions and let the .cpp file #include the rest, or none and declare everything it needs as extern?
The reasoning behind the question is the same as above: I don't want surprises when including .h files.
Also, if I am right, is this a common mistake? I mean in real-world programming and in "real" projects out there.
Thank you.
You should definitely NOT use using namespace in headers for precisely the reason you say, that it can unexpectedly change the meaning of code in any other files that include that header. There's no way to undo a using namespace which is another reason it's so dangerous. I typically just use grep or the like to make sure that using namespace isn't being called out in headers rather than trying anything more complicated. Probably static code checkers flag this too.
The header should include just the headers that it needs to compile. An easy way to enforce this is to always include each source file's own header as the first thing, before any other headers. Then the source file will fail to compile if the header isn't self-contained. In some cases, for example referring to implementation-detail classes within a library, you can use forward declarations instead of #include because you have full control over the definition of such forward declared class.
I'm not sure I would call it common, but it definitely shows up once in a while, usually written by new programmers that aren't aware of the negative consequences. Typically just a little education about the risks takes care of any issues since it's relatively simple to fix.
Item 59 in Sutter and Alexandrescu's "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices":
59. Don’t write namespace usings in a header file or before an #include.
Namespace usings are for your convenience, not for you to inflict on others: Never write a using declaration or a using directive before an #include directive.
Corollary: In header files, don't write namespace-level using directives or using declarations; instead, explicitly namespace-qualify all names.
A header file is a guest in one or more source files. A header file that includes using directives and declarations brings its rowdy buddies over too.
A using declaration brings in one buddy. A using directive brings in all the buddies in the namespace. Your teachers' use of using namespace std; is a using directive.
More seriously, we have namespaces to avoid name clash. A header file is intended to provide an interface. Most headers are agnostic of what code may include them, now or in the future. Adding using statements for internal convenience within the header foists those convenient names on all the potential clients of that header. That can lead to name clash. And it's just plain rude.
You need to be careful when including headers inside of headers. In large projects, it can create a very tangled dependency chain that triggers larger/longer rebuilds than were actually necessary. Check out this article and its follow-up to learn more about the importance of good physical structure in C++ projects.
You should only include headers inside a header when absolutely needed (whenever the full definition of a class is needed), and use forward declaration wherever you can (when the class is required is a pointer or a reference).
As for namespaces, I tend to use the explicit namespace scoping in my header files, and only put a using namespace in my cpp files.
With regards to "Is there some way to undo [a using declaration]?"
I think it is useful to point out that using declarations are affected by scope.
#include <vector>
{ // begin a new scope with {
using namespace std;
vector myVector; // std::vector is used
} // end the scope with }
vector myOtherVector; // error vector undefined
std::vector mySTDVector // no error std::vector is fully qualified
So effectively yes. By limiting the scope of the using declaration its effect only lasts within that scope; it is 'undone' when that scope ends.
When the using declaration is declared in a file outside of any other scope it has file-scope and affects everything in that file.
In the case of a header file, if the using declaration is at file-scope this will extend to the scope of any file the header is included in.
Check out the Goddard Space Flight Center coding standards (for C and C++). That turns out to be a bit harder than it used to be - see the updated answers to the SO questions:
Should I use #include in headers
Self-sufficient headers in C and C++
The GSFC C++ coding standard says:
§3.3.7 Each header file shall #include the files it needs to compile, rather than forcing users to #include the needed files. #includes shall be limited to what the header needs; other #includes should be placed in the source file.
The first of the cross-referenced questions now includes a quote from the GSFC C coding standard, and the rationale, but the substance ends up being the same.
You are right that using namespace in header is dangerous.
I do not know a way how to undo it.
It is easy to detect it however just search for using namespace in header files.
For that last reason it is uncommon in real projects. More experienced coworkers will soon complain if someone does something like it.
In real projects people try to minimize the amount of included files, because the less you include the quicker it compiles. That saves time of everybody. However if the header file assumes that something should be included before it then it should include it itself. Otherwise it makes headers not self-contained.
You are right. And any file should only include the headers needed by that file. As for "is doing things wrong common in real world projects?" - oh, yes!
Like all things in programming, pragmatism should win over dogmatism, IMO.
So long as you make the decision project-wide ("Our project uses STL extensively, and we don't want to have to prepend everything with std::."), I don't see the problem with it. The only thing you're risking is name collisions, after all, and with the ubiquity of STL it's unlikely to be a problem.
On the other hand, if it was a decision by one developer in a single (non-private) header-file, I can see how it would generate confusion among the team and should be avoided.
I believe you can use 'using' in C++ headers safely if you write your declarations in a nested namespace like this:
namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED
{
/*using statements*/
namespace DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED
{
/*declarations*/
}
}
using namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED::DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED;
This should include only the things declared in 'DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED' without the namespaces used. I have tested it on mingw64 compiler.

Calling an "external" function from a class method

I have a function that I want to call from within a class method. The function is in a file called mergeSort.cpp. Here is a snippet of the .cpp file that the class is implemented in:
// other includes
#include "mergeSort.cpp"
// other methods
void Servers::sortSites() {
mergeSort(server_sites.begin(), server_sites.end(), siteCompare);
}
// remaining methods
When I try to compile I get errors saying that mergeSort can't be found. I think this is because it's trying to call Servers::mergeSort. How would I go about calling an external function?
You have to use the "::" external namespace resolutor:
::mergeSort(...);
This tells the compiler to look for the function in the outer namespace. If this particular function is defined in another namespace or class, you have to specify it explicitly:
Namespace::mergeSort(...);
If you don't want to have to resolve the name completely each time you use it, you can import the name into the current namespace by either using:
using namespace Namespace;
or
using Namespace::mergeSort;
(where Namespace is the name in which mergeShort() is defined).
There seem to be a couple of issues here. Firstly, does Servers::mergeSort actually exist? You've speculated that it's looking for that, but you haven't actually said that there is such a thing. If there isn't, that's not the problem. In that case, a likely reason it can't see mergeSort would be that it's not in the global namespace (as other answers have speculated). If Servers::mergeSort does exist, then see Diego's answer.
A separate issue is -- are you including the .cpp file (which is generally a bit odd) because mergeSort is a template? If no, you should probably be including the accompanying .h I guess. If yes, a more usual pattern is to include the file with the template code in the header, like so:
// mergeSort.h
// <Begin include guard
// <Lots of header stuff>
#include "mergeSort.tpp"
// <End include guard>
Then you include mergeSort.h elsewhere, and it's one thing less for clients to remember.
Check if mergeSort() is in a particular namespace.

How to resolve a naming conflict between two libraries in C++?

I am using two large libraries (GUI & network) and I can happily do
using namespace FirstLib;
using namespace SecondLib;
Except for 1 single class called Foobar where names clash.
I my code, I do not use FirstLib::Foobar. Is there a way to say "in my code, whenever you see Foobar, think SecondLib::Foobar ?
using namespace is evil! Namespaces were made to prevent such problems as you have! But that said, try:
using namespace FirstLib;
using namespace SecondLib;
using SecondLib::Foobar;
or even (for some compilers):
using namespace FirstLib;
using namespace SecondLib;
typedef SecondLib::Foobar Foobar;
It's strange nobody suggested to replace the full namespace use by the list of used class names. This solution is even in the C++faq (where I should have thought to look first).
If we cannot say
include all FirstLib, but remove SecondLib::Foobar
We can use using-declarations of the exact elements we need:
using FirstLib::Boids;
using FirstLib::Life;
// no using FirstLib::Foobar...
You've basically answered your own question. You must explicitly say which class you want to use, so you must do SecondLib::Foobar whenever you use that class.
You have to pick one of these namespaces and get rid of the 'using', and explicitly call out all the class names. C# has a way around this, but C++ does not afaik...
I don't think there's a way of excluding names. You either bring in the whole lot, or each one individually. Even when you bring in the whole lot, you can always disambiguate conflicting names by qualifying them fully.
However, you could use typedef to rename the offending class:
typedef Lib2::FooBar FooBaz;
And I guess, with a conflicting function, you could use a function pointer to "rename" the conflicting one.
I guess it's kind of a non-solution. I can understand the occasional motivation to use using declarations - sometimes there are indeed many different names that you'll use all over the place - but if just one is conflicting: be explicit. It would be confusing to anyone familiar with the libraries anyway, seeing that both namespaces are imported.
Also, using declarations respect scope: you can make one namespace visible in one function, but not the other namespace - assuming you don't even use it in that function.
Have you tried:
using SecondLib::Foobar;
?
If you load all elements from both namespace to current scope by use of using namespace directove:
using namespace FirstLib;
using namespace SecondLib;
and there is potential that some of the names in those namespace may clash, then you need to tell compiler explicitly which of the element you want to use, in current scope, by use of using declaration:
using SecondLib::Foobar;
As the C++ standard says:
7.3.3 The using declaration
1 A using-declaration introduces a
name into the declarative region in
which the using-declaration appears.
That name is a synonym for the name of
some entity declared elsewhere.
This line requests compiler to think SecondLib::Foobar whenever it sees Foobar for the rest of current scope in which the using declaration was used.
The using directive and declaration is very helpful, but they may cause problems as the one you're dealing with. So, it's a good idea to narrow use of any form of using to minimal scope possible. You can use the directive using namespace in scope of other namespace
namespace MyApp {
using namespace ::SecondLib;
}
or even a function. The same applies to using declaration. So, it's a good idea to narrow the scope of use of any of them:
void foo()
{
::SecondLib::Foobar fb;
}
It may seem tedious, but it is only when you type, though you most likely use intellisense-enabled editor, so cost is really small, but benefits are large - no confusions, readable code, no compilation issues.
It's also a very good idea to NOT to use using namespace in header scope. See Header files usage - Best practices - C++
My own tip: do use full qualification whenever you need to use any of these types