I came across an expression that states: vector<int> pair(n). As pair is an inbuilt structure in itself, can we use it as a variable name in c++ and why??
As pair is an inbuilt structure in itself, can we use it as a variable name in c++ and why?
That is not correct. The Standard Template Library provides a class template called "pair" but that is not an inbuilt type and, furthermore, "pair" is neither a keyword nor a reserved word in the C++ language.
Furthermore, the aforementioned "pair" template is actually provided (in the <utility> header) in the std namespace, so its fully qualified name is std::pair. So, unless you both #include <utility> (explicitly or implicitly) and are using std::pair; (or using namespace std; – but see here), you can use the name, "pair," as an identifier, just like any other non-reserved word.
In fact, even if you do #include <utility> and are using std::pair; (or using namespace std;), you can still use "pair" as an identifier, as mentioned the comment by chris.
Yes, you can. The templates from the standard library are called std::pair and std::vector. They are not built-in, in the sense that they aren't part of the language, but part of the standard library. Hence this is not a problem:
#include <vector>
std::vector<int> pair(n);
One can use using directives to drop the std:: prefix:
#include <vector>
using std::vector;
vector<int> pair(n);
Commonly used is also using namespace std;:
#include <vector>
using namespace std;
vector<int> pair(n);
Though, once you pulled the complete namespace into scope, the code can be rather confusing.
Read Why is “using namespace std;” considered bad practice? and try to avoid it. And give proper names. std::pair is rather common, so you better choose a better name for the vector, it certainly is not a pair.
std::pair is not an "in-built structure". It's a qualified name from the Standard Library. Since it's qualified, it generally does not clash with your own names.
This is exactly why namespaces were added to the C++ language.
Related
I would like to use the string class.
Should I also involve using namespace std;?
I thought #include <string> would be enough but in CLion when only one of these two (namespace or include) is absent, there are some errors.
What makes things more complicated, is that there is <string> or <strings.h>. What's the difference?
<string> is C++ and provides the std::string class.
<string.h> is C (the C++ equivalent is <cstring>) and only provides functions to work on char*.
Don't use using namespace std; (see the C++ Core Guidelines).
In C++ the using statement is not related to including the functionality of that namespace (or type). Instead, it allows you to use the namespace in the statement without a namespace prefix in the rest of the current scope (or compilation unit if you have the statement in global scope) after the using statement.
So you could either write
#include <string>
std::string my_string;
or
#include <string>
using namespace std;
string my_string;
As others have mentioned - the first version is more recommended than the second, because there's usually a reason that things are in their own namespace (such as the std namespace here). If you have a blanket using statement you may get unexpected name clashes or other issues. This is especially true if you do it in a header file, which you should never do unless you know exactly what the results will be and where.
This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 7 years ago.
Two ways to use the using declaration are
using std::string;
using std::vector;
or
using namespace std;
which way is better?
It depends.
If you want to inject a single name into another scope, the using-declaration is better, e.g.
namespace foolib
{
// allow vector to be used unqualified within foo,
// or used as foo::vector
using std::vector;
vector<int> vec();
template<typename T> struct Bar { T t; };
template<typename T>
void swap(Bar<T>& lhs, Bar<T>& rhs)
{
using std::swap;
// find swap by ADL, otherwise use std::swap
swap(lhs.t, rhs.t);
}
}
But sometimes you just want all names, which is what a using-directive does. That could be used locally in a function, or globally in a source file.
Putting using namespace outside a function body should only be done where you know exactly what's being included so it's safe (i.e. not in a header, where you don't know what's going to be included before or after that header) although many people still frown on this usage (read the answers at Why is "using namespace std" considered bad practice? for details):
#include <vector>
#include <iostream>
#include "foolib.h"
using namespace foo; // only AFTER all headers
Bar<int> b;
A good reason to use a using-directive is where the namespace only contains a small number of names that are kept intentionally segregated, and are designed to be used by using-directive:
#include <string>
// make user-defined literals usable without qualification,
// without bringing in everything else in namespace std.
using namespace std::string_literals;
auto s = "Hello, world!"s;
So there is no single answer that can say one is universally better than the other, they have different uses and each is better in different contexts.
Regarding the first usage of using namespace, the creator of C++, Bjarne Stroustrup, has this to say in §14.2.3 of The C++ Programming Language, 4th Ed (emphasis mine):
Often we like to use every name from a namespace without qualification. That can be achieved by providing a using-declaration for each name from the namespace, but that's tedious and requires extra work each time a new name is added to or removed from the namespace. Alternatively, we can use a using-directive to request that every name from a namespace be accessible in our scope without qualification. [...]
[...] Using a using-directive to make names from a frequently used and well-known library available without qualification is a popular technique for simplifying code. This is the technique used to access standard-library facilities throughout this book. [...]
Within a function, a using-directive can be safely used as a notational convenience, but care should be taken with global using-directives because overuse can lead to exactly the name clashes that namespaces were introduced to avoid. [...]
Consequently, we must be careful with using-directives in the global scope. In particular, don't place a using-directive in the global scope in a header file except in very specialized circumstances (e.g. to aid transition) because you never know where a header might be #included.
To me this seems far better advice than just insisting it is bad and should not be used.
using std::string; and using std::vector;.
Polluting the global namespace with a bunch of symbols is a bad idea. You should just use the std namespace prefix too, so you know that you're using standard library containers. Which is better than both options IMO.
If you are simply using the standard library and nothing else and never will be adding in any other libraries to your project, by all means, use using namespace std; - Whatever you feel more comfortable with in that situation. The convention of "never use using namespace std;" comes from the fact that multiple other libraries define things such as string, vector and such. It is good practice to never import the whole namespace, but it should cause no bothers in your case.
In the stlport library, I saw this code:
namespace std { }
namespace __std_alias = std;
1. Are they trying to nullify the standard std namespace in the first line?
2. Why in the world would they use a longer alias name in place of the original name?
You need the namespace "in scope" before you can declare an alias to it. The empty namespace std {} informs the compiler that the namespace exists. Then they can create an alias to it.
There are reasons for creating aliases besides creating a shortcut. For example, you can define a macro to "rename" the namespace -- consider the effect of #define std STLPORT_std. Having a alias allows you to access the original namespace provided that you play the correct ordering games with header files.
No, that just makes sure the namespace's name is available in the current scope. You can open and close namespaces at any point, without affecting the contents of the namespace.
I would guess, so they could easily change their library implementation to be in a namespace other than ::std (by changing __std_alias to alias something else). This would be useful, for example, if you want to test two implementations alongside each other.
It is rather annoying to get a compiler error that there is no such namespace as std... What is the compiler thinking? Of course it exists!
Well yes it does, but as with library features, it has to be declared first. That is what the first line is doing.
With the renaming of __std_alias it allows them to give a new alias to a namespace. You may decide to do this in your own code someday.
Perhaps you want to use shared_ptr in your code but do not want to dedicate your code to using namespace boost or std. So you can create an alias, and "point" it at either boost or std. Same with other features that are in boost libraries that later became standard.
This does not tie you to using this namespace for everything as you can have more than one alias, and you can have more than one pointing to the same real namespace.
Let's say we want to call our smart pointer library sml. We can do
namespace sml = boost; // or std
in one place in the code and #include <boost/shared_ptr.hpp> from that point in the code (same header).
Everywhere else in our code we use sml::shared_ptr. If we ever switch from boost to std, just change the one header, not all your code.
In addition to what D.Shawley said, forward declaring a class that's inside a namespace requires the same syntax:
namespace std
{
template <typename T>
class vector;
}
I am working on a very big and old C++ project. The word "vector" has been used all over the place. I am now trying to add new functionality to the project utilizing STL vector. This is not working. In addition, I am only allowed to modify specific sections of the code, so I can not change their use of "vector".
Is there a way to rename STL vector and use it?
Use C++ namespaces.
#include <vector>
// note the absence of `using namespace std;` line
int main() {
// note the `std::` qualification
std::vector<int> x;
// ...
}
As long as you don't put using namespace std; anywhere (which is not a great thing to do anyway), there will be no conflict between ::std::vector and any other vector.
I'm assuming that this infinite wisdom didn't extend to declaring names inside std; in that case, my best advice is to run away. I'm also assuming that you're talking about the modern C++ library, not the STL which (I think) didn't have its own namespace.
Remove the using namespace std; from the beginning of the file, and add std:: in the code wherever is needed:
std::cout << "debug" << std::endl;
std::vector<std::string> simple_vector;
Just refer to it using the full name std::vector.
In C++11, you could also use a using statement.
Don't do this.
#define vector stdVector
#include <vector>
#undef vector
End of don't do this
You can either use namespaces to qualify your version of vector or the one from std, after you remove the using directives.
In my header file I'm getting the
error: ‘string’ has not been declared
error but at the top of the file I have #include <string>, so how can I be getting this error?
string resides in the std namespace, you have to use std::string or introduce it into the scope via using directives or using declarations.
Use
std::string var;
or
using namespace std;
string var;
String is in a std namespace so you must let your compiler know.
Most of the classes and class templates, and instances of those classes, defined by the Standard Library (like string and cout) are declared in the std:: namespace, not in the global namespace. So, whenever you want to use (say) string, the class is actually std::string.
You can add that namespace prefix explicitly every time you use such a class, but that can become tedious. In order to help, you can add using declarations for those classes you use frequently.
So, in your case, you could add lines like the following, generally somewhere shortly after the corresponding #include lines:
#include <string>
#include <iostream>
using std::string;
using std::cout; // Added as illustrative examples of other
using std::endl; // ... elements of the Standard Library
Or, if you have a compiler that supports the C++17 Standard (or later), you can put more than one class in the same statement:
using std::string, std::cout, std::endl; // C++17 or later
But, beware of using the generic, "cover-all" using namespace std; directive (even though that is actually valid C++ syntax). See: Why is "using namespace std;" considered bad practice?
For a more general introduction to, and overview of, the Standard Template Library (now, more correctly known as the C++ Standard Library), see the tag-Wiki for the stl tag.