what is the use of using declaration type of namespacing over using directive type of namespacing??when to use each one of them?
The declaration type of namespace directive introduces selected named symbols into your code scope (and leaves other symbols from the same namespace inaccessible without the namespace qualifier).
The using type of namespace directive introduces all symbols from the namespace into your code scope - which means you don't necessarily know exactly which symbols were introduced (there could have been undocumented symbols, or symbols left over from previous versions of the library, or ...).
For control, use the declaration type of namespace directive.
For convenience (with risk), use the using type of namespace directive.
Besides the using declaration allowing access to a symbol rather than a namespace, the using declaration also brings the symbol to the scope of the declaration. The using directive only affects lookup.
Jonathan already resumed the differences between using namespace foo; and using foo::Bar; but I think his answer is unfortunately incomplete.
First: using namespace should never appear in a header file. By doing so you might render it impossible to use in combination with other header files because of a symbol clash...
Second: in general, you should try to limit the scope of the symbols as much as possible, you probably already do it while writing code:
for (size_t i = 0; i < 5; ++i)
{
std::string myString = myVec.at(i);
if (myString == "Foo") { std::cout << "Found"; break; }
}
Here it would be useless (and polluting) to have myString declared outside the for loop. In fact, that very advice can be found in a number of books:
From Scott Meyers' Effective C++, Item 26: Postpone variable definitions as long as possible.
From Herb Sutter and Andrei Alexandrescu's C++ Coding Standard, Item 18: Declare variables as locally as possible
There is no reason not to do the same with using declarations.
Third: consider alternatives to using: namespace aliasing and typedef.
// foo.h
class Foo
{
public:
std::vector<std::string> getSynonyms(const std::string& s) const;
private:
typedef std::map< std::string, std::vector<std::string> > synonyms_type;
synonyms_type mSynonyms;
};
// foo.cpp (never in header, at general scope)
namespace fu = boost::fusion;
std::vector<std::string> Foo::getSynonyms(const std::string& s) const
{
synonyms_type::const_iterator it =
std::find(mSynonyms.begin(), mSynonyms.end(), s);
std::vector<std::string> result;
if (it != mSynonyms.end()) { result = it->second; }
return result;
}
What are the advantages ?
namespace aliasing > reduce typing almost as much without injecting the types right in the current scope so without risk
typedef > reduce typing more than using and allow easy change of underlying type too.
Related
In the C++-Standard (eg. N4594) there are two definitions for operator""s:
One for std::chrono::seconds :
namespace std {
...
inline namespace literals {
inline namespace chrono_literals {
// 20.15.5.8, suffixes for duration literals
constexpr chrono::seconds operator "" s(unsigned long long);
and one for std::string :
namespace std {
....
inline namespace literals {
inline namespace string_literals {
// 21.3.5, suffix for basic_string literals:
string operator "" s(const char* str, size_t len);
I wonder what is gained from those namespaces (and all the other namespaces inside std::literals), if they are inline.
I thought they were inside separate namespaces so they do not conflict with each other. But when they are inline, this motivation is undone, right? Edit: Because Bjarne explains the main motivation is "library versioning", but this does not fit here.
I can see that the overloads for "Seconds" and "String" are distinct and therefor do not conflict. But would they conflict if the overloads were the same? Or does take the (inline?) namespace prevents that somehow?
Therefore, what is gained from them being in an inline namespace at all?
How, as #Columbo points out below, are overloading across inline namespaces resolved, and do they clash?
The user-defined literal s does not "clash" between seconds and string, even if they are both in scope, because they overload like any other pair of functions, on their different argument lists:
string operator "" s(const char* str, size_t len);
seconds operator "" s(unsigned long long sec);
This is evidenced by running this test:
void test1()
{
using namespace std;
auto str = "text"s;
auto sec = 1s;
}
With using namespace std, both suffixes are in scope, and yet do not conflict with each other.
So why the inline namespace dance?
The rationale is to allow the programmer to expose as few std-defined names as desired. In the test above, I've "imported" the entire std library into test, or at least as much as has been #included.
test1() would not have worked had namespace literals not been inline.
Here is a more restricted way to use the literals, without importing the entire std:
void test2()
{
using namespace std::literals;
auto str = "text"s;
auto sec = 1s;
string str2; // error, string not declared.
}
This brings in all std-defined literals, but not (for example) std::string.
test2() would not work if namespace string_literals was not inline and namespace chrono_literals was not inline.
You can also choose to just expose the string literals, and not the chrono literals:
void test3()
{
using namespace std::string_literals;
auto str = "text"s;
auto sec = 1s; // error
}
Or just the chrono literals and not the string literals:
void test4()
{
using namespace std::chrono_literals;
auto str = "text"s; // error
auto sec = 1s;
}
Finally there is a way to expose all of the chrono names and the chrono_literals:
void test5()
{
using namespace std::chrono;
auto str = "text"s; // error
auto sec = 1s;
}
test5() requires this bit of magic:
namespace chrono { // hoist the literals into namespace std::chrono
using namespace literals::chrono_literals;
}
In summary, the inline namespaces are a tool to make all of these options available to the developer.
Update
The OP asks some good followup questions below. They are (hopefully) addressed in this update.
Is using namespace std not a good idea?
It depends. A using namespace is never a good idea at global scope in a header that is meant to be part of a general purpose library. You don't want to force a bunch of identifiers into your user's global namespace. That namespace belongs to your user.
A global scope using namespace can be ok in a header if the header only exists for the application you are writing, and if it is ok with you that you have all of those identifiers available for everything that includes that header. But the more identifiers you dump into your global scope, the more likely it is that they will conflict with something. using namespace std; brings in a bunch of identifiers, and will bring in even more with each new release of the standard. So I don't recommend using namespace std; at global scope in a header even for your own application.
However I could see using namespace std::literals or using namespace std::chrono_literals at global scope in a header, but only for an application header, not a library header.
I like to use using directives at function scope as then the import of identifiers is limited to the scope of the function. With such a limit, if a conflict does arise, it is much easier to fix. And it is less likely to happen in the first place.
std-defined literals will probably never conflict with one another (they do not today). But you never know...
std-defined literals will never conflict with user-defined literals because std-defined literals will never start with _, and user-defined literals have to start with _.
Also, for library developers, is it necessary (or good practice) to have no conflicting overloads inside several inline namespaces of a large library?
This is a really good question, and I posit that the jury is still out on this one. However I just happen to be developing a library that purposefully has conflicting user-defined literals in different inline namespaces!
https://github.com/HowardHinnant/date
#include "date.h"
#include "julian.h"
#include <iostream>
int
main()
{
using namespace date::literals;
using namespace julian::literals;
auto ymd = 2017_y/jan/10;
auto jymd = julian::year_month_day{ymd};
std::cout << ymd << '\n';
std::cout << jymd << '\n';
}
The above code fails to compile with this error message:
test.cpp:10:20: error: call to 'operator""_y' is ambiguous
auto ymd = 2017_y/jan/10;
^
../date/date.h:1637:1: note: candidate function
operator "" _y(unsigned long long y) NOEXCEPT
^
../date/julian.h:1344:1: note: candidate function
operator "" _y(unsigned long long y) NOEXCEPT
^
The _y literal is used to create year in this library. And this library has both a Gregorian calendar (in "date.h") and a Julian calendar (in "julian.h"). Each of these calendars has a year class: (date::year and julian::year). They are different types because the Gregorian year is not the same thing as a Julian year. But it is still convenient to name them both year and to give them both a _y literal.
If I remove the using namespace julian::literals; from the code above then it compiles and outputs:
2017-01-10
2016-12-28
which is a demonstration that 2016-12-28 Julian is the same day as 2017-01-10 Gregorian. And this is also a graphic demonstration that the same day can have different years in different calendars.
Only time will tell if my use of conflicting _ys will be problematic. To date it hasn't been. However not many people have used this library with non-Gregorian calendars.
I'm a newbie in c++.
Why, in Eclipse (configured with MinGW) and also in other threads, I noticed is used to add a class to a namespace?
I provide an example to show you my actual doubt:
#ifndef MODEL_MANGO_HPP_
#define MODEL_MANGO_HPP_
namespace std {
class Mango {
public:
Mango();
virtual ~Mango();
};
} /* namespace std */
#endif /* MODEL_MANGO_HPP_ */
EDIT: As shown in comments, it's completely forbidden to add classes to namespace std. Quoting #owacoder,
Namespaces are never closed, so you always have the ability to add
class definitions to them. However, by the specification the std
namespace is to be considered closed.
To provide you a complete view of the context, here is the default implementation of the Mango.cpp, that Eclipse has done for me:
#include "Mango.hpp"
namespace std {
Mango::Mango() {
// TODO Auto-generated constructor stub
}
Mango::~Mango() {
// TODO Auto-generated destructor stub
}
} /* namespace std */
So my question changes into:
Why it's used "namespace std {...}" and when is a good practice to add classes to a namespace?
You have to understand the basics of what classes and namespaces are.
classes (along with structs, enums, and enum classes) are used to define user defined types in C++.
You create a class to represent a logical entity and encapsulate details, etc.
namespaces are a way to mark territories of code and qualifying unique names for variables.
if you just write a class in a file, it will be written in the "global namespace" and it is not considered good practice because you are "polluting the namespace".
instead, you should use namespaces to limit the scope where your variable names have meaning. this way, you are not exhausting the pool of sensible class and variable names quickly (how many times have you wanted to write a "Utility" class?)
namespace firstNamespace{
int x=2;
}
namespace secondNamespace{
int x=7;
}
int main ()
{
std::cout << firstNamespace::x << '\n';
std::cout << secondNamespace::x << '\n';
return 0;
}
in this case, you can see that we can "reuse" the variable name x in different Contexts by qualifying a namespace. inside the namespace blocks, we could have more declarations and definitions. including functions, classes, structs, etc.
take not that namespaces remain open and you can add to them later.
for example you can have this:
namespace firstNamespace{
int x=2;
}
namespace secondNamespace{
int x=7;
}
namespace firstNamespace{
int y=11;
}
here, we added firstNamespace::y.
More importantly, you can observe that std is a namespace provided by C++ that contains a lot of useful variables, objects like cout which is of type std::ostream, functions and classeslike std::vector, std::ostream, etc.
so to go back to your question, the reason you want to wrap your class definitions in namespaces is to not pollute the global namespace.
Eugh, 2 problems in one day. I am having one of those bad days you hear so much about. I have been organizing my small project to make it less cluttered. It's at the start of the development so there isn't much going on. I have this header below
#pragma once
#include <string>
class Game_Map
{
private:
int map_width;
int map_height;
string map_data [50][50]
public:
Game_Map(int default_width = 20,int default_height = 20)
~Game_Map()
};
Now as far as I can see, there shouldn't be any problems. I avoided using the "using" and I kept the programming up til now at the basic to prevent external interference. But am I 100% of the time getting "map.h:9:9: error: 'string' does not name a type"
I am certain I have missed something. Can anyone see where I have gone wrong?
Change
string map_data [50][50]
to
std::string map_data [50][50];
That's necessary because string belongs to the std namespace.
Don't use "using" declaration or directive in a header file.
Use either a fully qualified name (preferable) as
std::string map_data [50][50];
or use using declaration
using std::string;
string map_data [50][50];
or using directive
using namespace std;
string map_data [50][50]'
You seem to miss some semicolons at the end of some lines here:
class Game_Map
{
...
string map_data [50][50] // Missing ;
public:
Game_Map(int default_width = 20,int default_height = 20) // Missing ;
~Game_Map() // Missing ;
};
Moreover, when you #include <string>, the "complete name" to identify the STL string class is std::string (since the STL string class is located under the std:: namespace).
So, just use std::string instead of string in this line:
std::string map_data[50][50];
Note that in header files you shouldn't use "using directives" (e.g. using namespace std;), to avoid to "pollute" the global namespace of clients that #include your header file.
Just specify the STL class names with their std:: prefix in header files.
With one of my projects I will head into the C++ field. Basically I am coming
from a Java background and was wondering how the concept of Java packages
is realized in the C++ world. This led me to the C++ concept of namespaces.
I am absolutely fine with namespaces so far but when it comes to header files
things are becoming kind of inefficient with respect to fully qualified class
names, using-directives and using-declarations.
A very good description of the issue is this article by Herb Sutter.
As I understand it this all boils down to: If you write a header file always
use fully qualified type names to refer to types from other namespaces.
This is almost unacceptable. As a C++ header commonly provides the declaration
of a class, a maximum of readability has top priority. Fully qualifying each
type from a different namespace creates a lot of visual noise, finally
diminishing readability of the header to a degree which raises the question
whether to use namespaces at all.
Nevertheless I want to take advantage of C++ namespaces and so put some thought into
the question: How to overcome the namespace evil of C++ header files? After
some research I think typedefs could be a valid cure to this problem.
Following you will find a C++ sample program which demonstrates how I would
like to use public class scoped typedefs to import types from other namespaces.
The program is syntactically correct and compiles fine on MinGW W64. So far so
good, but I am not sure whether this approach happily removes the using keyword
from the header but brings in another problem which I am simply not aware of.
Just something tricky like the things described by Herb Sutter.
That is I kindly ask everybody who has a thorough understanding of C++ to
review the code below and let me know whether this should work or not. Thanks
for your thoughts.
MyFirstClass.hpp
#ifndef MYFIRSTCLASS_HPP_
#define MYFIRSTCLASS_HPP_
namespace com {
namespace company {
namespace package1 {
class MyFirstClass
{
public:
MyFirstClass();
~MyFirstClass();
private:
};
} // namespace package1
} // namespace company
} // namespace com
#endif /* MYFIRSTCLASS_HPP_ */
MyFirstClass.cpp
#include "MyFirstClass.hpp"
using com::company::package1::MyFirstClass;
MyFirstClass::MyFirstClass()
{
}
MyFirstClass::~MyFirstClass()
{
}
MySecondClass.hpp
#ifndef MYSECONDCLASS_HPP_
#define MYSECONDCLASS_HPP_
#include <string>
#include "MyFirstClass.hpp"
namespace com {
namespace company {
namespace package2 {
/*
* Do not write using-declarations in header files according to
* Herb Sutter's Namespace Rule #2.
*
* using std::string; // bad
* using com::company::package1::MyFirstClass; // bad
*/
class MySecondClass{
public:
/*
* Public class-scoped typedefs instead of using-declarations in
* namespace package2. Consequently we can avoid fully qualified
* type names in the remainder of the class declaration. This
* yields maximum readability and shows cleanly the types imported
* from other namespaces.
*/
typedef std::string String;
typedef com::company::package1::MyFirstClass MyFirstClass;
MySecondClass();
~MySecondClass();
String getText() const; // no std::string required
void setText(String as_text); // no std::string required
void setMyFirstInstance(MyFirstClass anv_instance); // no com::company:: ...
MyFirstClass getMyFirstInstance() const; // no com::company:: ...
private:
String is_text; // no std::string required
MyFirstClass inv_myFirstInstance; // no com::company:: ...
};
} // namespace package2
} // namespace company
} // namespace com
#endif /* MYSECONDCLASS_HPP_ */
MySecondClass.cpp
#include "MySecondClass.hpp"
/*
* According to Herb Sutter's "A Good Long-Term Solution" it is fine
* to write using declarations in a translation unit, as long as they
* appear after all #includes.
*/
using com::company::package2::MySecondClass; // OK because in cpp file and
// no more #includes following
MySecondClass::MySecondClass()
{
}
MySecondClass::~MySecondClass()
{
}
/*
* As we have already imported all types through the class scoped typedefs
* in our header file, we are now able to simply reuse the typedef types
* in the translation unit as well. This pattern shortens all type names
* down to a maximum of "ClassName::TypedefTypeName" in the translation unit -
* e.g. below we can simply write "MySecondClass::String". At the same time the
* class declaration in the header file now governs all type imports from other
* namespaces which again enforces the DRY - Don't Repeat Yourself - principle.
*/
// Simply reuse typedefs from MySecondClass
MySecondClass::String MySecondClass::getText() const
{
return this->is_text;
}
// Simply reuse typedefs from MySecondClass
void MySecondClass::setText(String as_text)
{
this->is_text = as_text;
}
// Simply reuse typedefs from MySecondClass
void MySecondClass::setMyFirstInstance(MyFirstClass anv_instance)
{
this->inv_myFirstInstance = anv_instance;
}
// Simply reuse typedefs from MySecondClass
MySecondClass::MyFirstClass MySecondClass::getMyFirstInstance() const
{
return this->inv_myFirstInstance;
}
Main.cpp
#include <cstdio>
#include "MySecondClass.hpp"
using com::company::package2::MySecondClass; // OK because in cpp file and
// no more #includes following
int main()
{
// Again MySecondClass provides all types which are imported from
// other namespaces and are part of its interface through public
// class scoped typedefs
MySecondClass *lpnv_mySecCls = new MySecondClass();
// Again simply reuse typedefs from MySecondClass
MySecondClass::String ls_text = "Hello World!";
MySecondClass::MyFirstClass *lpnv_myFirClsf =
new MySecondClass::MyFirstClass();
lpnv_mySecCls->setMyFirstInstance(*lpnv_myFirClsf);
lpnv_mySecCls->setText(ls_text);
printf("Greetings: %s\n", lpnv_mySecCls->getText().c_str());
lpnv_mySecCls->setText("Goodbye World!");
printf("Greetings: %s\n", lpnv_mySecCls->getText().c_str());
getchar();
delete lpnv_myFirClsf;
delete lpnv_mySecCls;
return 0;
}
Pain is mitigated by reducing complexity. You're bending C++ into Java. (That works just as bad as trying the other way.)
Some hints:
Remove the "com" namespace level. (This is just a java-ism that you don't need)
Drop the "company" namespace, maybe replace by "product" or "library" namespace (i.e. boost, Qt, OSG, etc). Just pick something that's unique w.r.t. the other libs you're using.
You don't need to fully declare names that are in the same namespace you're in (caveat emptor: template classe, see comment). Just avoid any using namespace directives in the headers. (And use with care in C++ files, if at all. Inside functions is preferred.)
Consider namespace aliases (in functions/cpp files), i.e namespace bll = boost::lambda;. This creates shortcuts that are quite neat.
Also, by hiding private members/types using the pimpl pattern, your header have less types to expose.
P.S: Thanks to #KillianDS a few good tips in comments (that were deleted when I edited them into the question.)
Is there any difference between wrapping both header and cpp file contents in a namespace or wrapping just the header contents and then doing using namespace in the cpp file?
By difference I mean any sort performance penalty or slightly different semantics that can cause problems or anything I need to be aware of.
Example:
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
namespace X
{
void Foo::TheFunc()
{
return;
}
}
VS
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
using namespace X;
{
void Foo::TheFunc()
{
return;
}
}
If there is no difference what is the preferred form and why?
The difference in "namespace X" to "using namespace X" is in the first one any new declarations will be under the name space while in the second one it won't.
In your example there are no new declaration - so no difference hence no preferred way.
Namespace is just a way to mangle function signature so that they will not conflict. Some prefer the first way and other prefer the second version. Both versions do not have any effect on compile time performance. Note that namespaces are just a compile time entity.
The only problem that arises with using namespace is when we have same nested namespace names (i.e) X::X::Foo. Doing that creates more confusion with or without using keyword.
There's no performance penalties, since the resulting could would be the same, but putting your Foo into namespace implicitly introduces ambiguity in case you have Foos in different namespaces. You can get your code fubar, indeed. I'd recommend avoiding using using for this purpose.
And you have a stray { after using namespace ;-)
If you're attempting to use variables from one to the other, then I'd recommend externalizing them, then initializing them in the source file like so:
// [.hh]
namespace example
{
extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
int a, b, c;
}
// Then in the function below, you can init them as what you want:
void reference
{
example::a = 0;
}
If the second one compiles as well, there should be no differences. Namespaces are processed in compile-time and should not affect the runtime actions.
But for design issues, second is horrible. Even if it compiles (not sure), it makes no sense at all.
The Foo::TheFunc() is not in the correct namespacein the VS-case. Use 'void X::Foo::TheFunc() {}' to implement the function in the correct namespace (X).
In case if you do wrap only the .h content you have to write using namespace ... in cpp file otherwise you every time working on the valid namespace. Normally you wrap both .cpp and .h files otherwise you are in risk to use objects from another namespace which may generate a lot of problems.
I think right thing to do here is to use namespace for scoping.
namespace catagory
{
enum status
{
none,
active,
paused
}
};
void func()
{
catagory::status status;
status = category::active;
}
Or you can do the following:
// asdf.h
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
Then
// asdf.cpp
#include "asdf.h"
void X::Foo::TheFunc()
{
return;
}