This question already has answers here:
C++ namespace and include
(11 answers)
Closed 5 years ago.
In order to use strings I need to include the string header, so that its implementation becomes available. But if that is so, why do I still need to add the line using std::string?
Why doesn't it already know about the string data type?
#include <string>
using std::string;
int main() {
string s1;
}
Because string is defined within namespace called std.
you can write std::string everywhere where <string> is included but you can add using std::string and don't use namespace in the scope (so std::string might be reffered to as string). You can place it for example inside the function and then it applies only to that function:
#include <string>
void foo() {
using std::string;
string a; //OK
}
void bar() {
std::string b; //OK
string c; //ERROR: identifier "string" is undefined
}
using std::string; doesn't mean you can now use this type, but you can use this type without having to specify the namespace std:: before the name of the type.
The following code is correct:
#include <string>
int main()
{
std::string s1;
return 0;
}
Because the declaration of class string is in the namespace std. Thus you either need to always access it via std::string (then you don't need to have using) or do it as you did.
Namespace is an additional feature of C++, which is defining the scope of a variable, function or object and avoiding the name collision. Here, the string object is defined in the std namespace.
std is the standard namespace. cout, cin, string and a lot of other things are defined in it.
The header <string> declares the various entities related to the strings library, whereas namespaces are used to group related functionality and allow use of the same names in different namespaces.
what is the difference between ::std::string and std::string
The former is global? But global for what?Is not namespace std global?
Thanks for helping me.
::std::string means string in namespace std in the global namespace. The leading :: forces the lookup to start in the global namespace. Therefore ::std::string always means the string type from the C++ standard library.
std::string means string in namespace std, where std will be looked up in the current scope. Therefore, if there is a class, namespace, or enum named std, name lookup might find that std.
#include <string>
namespace foo {
namespace std {
class string { ... };
namespace bar {
std::string s; // means foo::std::string
::std::string s; // means string from standard library
}
}
}
It is not necessary to use the leading :: as long as you and your collaborators agree to not name anything std. It's just good style.
I need to implement a class for one of my assignment and one of the function in the class that has string as datatype doesn't work
my definition code is :
#include <string>
class expression {
public:
expression();
void promptUser();
int getNum1();
int getNum2();
int calculate();
st::string str;
string numToString(int num);
string opToString();
private:
int num1;
int num2;
char op;
};
And in my implementation file
when I try to definite numTostring
string expression::numToString(int num) {
string digit;
...
It says that the declaration is incompatible with the header file(my class definition)
I have no idea why because both the function heading are the same.
the header file of expression.cpp( the implementation file) are :
#include "expression1.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
Your class uses the unqualified name string, but there is no string data type defined in any enclosing scopes. There's a std::string data type defined in namespace std. That's looks to be the type that you need:
std::string str;
std::string numToString(int num);
std::string opToString();
You can keep from having to type out std:: everywhere by specifying a using statement:
using std::string;
But you might not want to do that inside a header file, so stick with fully qualifying the type.
If you want to use , you need to refer to it with std::
For example, your expression class declares:
st::string str;
string numToString(int num);
string opToString();
Which should be:
std::string str; // you typed st:: instead of std::
std::string numToString(int num); // lack of std::
std::string opToString(); // lack of std::
If you dont use 2 files (cpp + h) to define and declare your class then you can add line
using namespace std;
just after your includes. This way you wont have to type std:: each time you try to refer to string and similar types. However, using this is often called a bad "beginner" practice.
If you do use cpp+h then just add std:: before every string type and add using namespace std; to your cpp file.
If you want to know more then read:
1. http://www.cplusplus.com/doc/tutorial/namespaces/
2. Why is "using namespace std" considered bad practice?
3. How do you properly use namespaces in C++?
You also need to move
#include "stdafx.h"
up so it is the first header included. The compiler ignores everything that comes before that magic line.
In C, if I use #include "someFile.h", the preprocessor does a textual import, meaning that the contents of someFile.h are "copy and pasted" onto the #include line. In C++, there is the using directive. Does this work in a similar way to the #include, ie: a textual import of the namespace?
using namespace std; // are the contents of std physically inserted on this line?
If this is not the case, then how is the using directive implemented`.
The using namespace X will simply tell the compiler "when looking to find a name, look in X as well as the current namespace". It does not "import" anything. There are a lot of different ways you could actually implement this in a compiler, but the effect is "all the symbols in X appear as if they are available in the current namespace".
Or put another way, it would appear as if the compiler adds X:: in front of symbols when searching for symbols (as well as searching for the name itself without namespace).
[It gets rather complicated, and I generally avoid it, if you have a symbol X::a and local value a, or you use using namespace Y as well, and there is a further symbol Y::a. I'm sure the C++ standard DOES say which is used, but it's VERY easy to confuse yourself and others by using such constructs.]
In general, I use explicit namespace qualifiers on "everything", so I rarely use using namespace ... at all in my own code.
No, it does not. It means that you can, from this line on, use classes and functions from std namespace without std:: prefix. It's not an alternative to #include. Sadly, #include is still here in C++.
Example:
#include <iostream>
int main() {
std::cout << "Hello "; // No `std::` would give compile error!
using namespace std;
cout << "world!\n"; // Now it's okay to use just `cout`.
return 0;
}
Nothing is "imported" into the file by a using directive. All it does is to provide shorter ways to write symbols that already exist in a namespace. For example, the following will generally not compile if it is the first two lines of a file:
#include <string>
static const string s("123");
The <string> header defines std::string, but string is not the same thing. You haven't defined string as a type, so this is an error.
The next code snippet (at the top of a different file) will compile, because when you write using namespace std, you are telling the compiler that string is an acceptable way to write std::string:
#include <string>
using namespace std;
static const string s("123");
But the following will not generally compile when it appears at the top of a file:
using namespace std;
static const string s("123");
and neither will this:
using namespace std;
static const std::string s("123");
That's because using namespace doesn't actually define any new symbols; it required some other code (such as the code found in the <string> header) to define those symbols.
By the way, many people will wisely tell you not to write using namespace std in any code. You can program very well in C++ without ever writing using namespace for any namespace. But that is the topic of another question that is answered at Why is "using namespace std" considered bad practice?
No, #include still works exactly the same in C++.
To understand using, you first need to understand namespaces. These are a way of avoiding the symbol conflicts which happen in large C projects, where it becomes hard to guarantee, for example, that two third-party libraries don't define functions with the same name. In principle everyone can choose a unique prefix, but I've encountered genuine problems with non-static C linker symbols in real projects (I'm looking at you, Oracle).
So, namespace allows you to group things, including whole libraries, including the standard library. It both avoids linker conflicts, and avoids ambiguity about which version of a function you're getting.
For example, let's create a geometry library:
// geo.hpp
struct vector;
struct matrix;
int transform(matrix const &m, vector &v); // v -> m . v
and use some STL headers too:
// vector
template <typename T, typename Alloc = std::allocator<T>> vector;
// algorithm
template <typename Input, typename Output, typename Unary>
void transform(Input, Input, Output, Unary);
But now, if we use all three headers in the same program, we have two types called vector, two functions called transform (ok, one function and a function template), and it's hard to be sure the compiler gets the right one each time. Further, it's hard to tell the compiler which we want if it can't guess.
So, we fix all our headers to put their symbols in namespaces:
// geo.hpp
namespace geo {
struct vector;
struct matrix;
int transform(matrix const &m, vector &v); // v -> m . v
}
and use some STL headers too:
// vector
namespace std {
template <typename T, typename Alloc = std::allocator<T>> vector;
}
// algorithm
namespace std {
template <typename Input, typename Output, typename Unary>
void transform(Input, Input, Output, Unary);
}
and our program can distinguish them easily:
#include "geo.hpp"
#include <algorithm>
#include <vector>
geo::vector origin = {0,0,0};
typedef std::vector<geo::vector> path;
void transform_path(geo::matrix const &m, path &p) {
std::transform(p.begin(), p.end(), p.begin(),
[&m](geo::vector &v) -> void { geo::transform(m,v); }
);
}
Now that you understand namespaces, you can also see that names can get pretty long. So, to save typing out the fully-qualified name everywhere, the using directive allows you to inject individual names, or a whole namespace, into the current scope.
For example, we could replace the lambda expression in transform_path like so:
#include <functional>
void transform_path(geo::matrix const &m, path &p) {
using std::transform; // one function
using namespace std::placeholders; // an entire (nested) namespace
transform(p.begin(), p.end(), p.begin(),
std::bind(geo::transform, m, _1));
// this ^ came from the
// placeholders namespace
// ^ note we don't have to qualify std::transform any more
}
and that only affects those symbols inside the scope of that function. If another function chooses to inject the geo::transform instead, we don't get the conflict back.
I have a problem with including header files in C++. As far as I know, it's not a good design to put using namespace std inside header but I got some error when I try to remove it. Here is my code in header file :
#include <iostream>
#include <string>
//using namespace std;
class Messages
{
public:
Messages(string sender, string recipient,int time);
void append();
string to_string();
private:
int time;
string sender;
string recipient;
string text;
};
I did include <string>. However, If I don't use namespace std, all my strings show errors. I do not want to add using namespace std in header file because it's a bad design. So how do I fix it?
Thanks in advance.
Just write std::string everywhere.
#include <iostream>
#include <string>
//using namespace std;
class Messages
{
public:
Messages(std::string sender, std::string recipient,int time);
void append();
std::string to_string();
private:
int time;
std::string sender;
std::string recipient;
std::string text;
};
Just as a rule of thumb: whenever (even in .cpp files) you are using any of the data types or algorithms from the Standard Library, just prefix it with std::. It's brief enough to type, and it will save you a world of pain.
There are some reasons for advanced users to use using declarations at function scope, e.g. when you want to overload a function (e.g. swap) from the Standard Library to work with your own data types (inside their own namespaces). See e.g. this Q&A on how that works.
The class string is declared inside the namespace std. You have three ways of addressing a class that's inside a different namespace:
By always writing <namespace>::<class>
By explicitly declaring that any reference to <class> actually means 1. above: using <namespace>::<class>;.
By declaring that any reference to a <class> that could not be resolved in the current namespace should also be looked up in an additional namespace: using namespace <namespace>;
Those are sorted in descending order of expressiveness. While 1. is perfectly clear wherever written, 3. can require some looking-up and scratching of heads if you are not familiar with the (possible multiple) namespaces used.
These are also sorted in descending order of typing involved, which is why some people (and especially textbooks) opt for 3.
However, you should never use using ... in a header file, because you are not only messing with the namespace resolution inside your header, but also with that of everyone including your header. This results in namespace collisions, strange errors depending on the order of includes and lots of other headaches. Just don't.
And generally speaking, while there is some pro and con involved with options 1. and 2. in implementation files, option 3. is simply offensive to anyone having to work with your source later on.