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.
Related
I'm a newbie to C++, and programming for the most part, just started learning a few days ago, and I'm a bit confused about this.
Is the string variable type in the standard namespace?
I found I can use strings without using #include <string>. I can also use using namespace std;, to activate the use of strings, or std::string mystring; for example.
I know that using using namespace std; allows for the use of all commands/functions within the standard namespace, ie cout.
If string is within the standard namespace, is #include <string> the same as saying using std::string; ?
std::string is a class defined in the standard library header <string>. Like all names of the standard library, it is declared in the namespace std.
is #include <string> the same as saying using std::string; ?
No. Those have two entirely different meanings.
#include <string> means "include the content of the header <string> into this file". The header contains the definition of the class std::string among other things.
using std::string; essentially means "declare the identifier string as a type alias to std::string in the current namespace".
"I found I can use strings without using #include <string>"
That's coincidence. You included another header that by chance included <string>. This is allowed in C++, and pretty common for e.g. <sstream>. But you can't rely on this. If you need std::string, you should #include <string>.
This will include std::string, from the std namespace. This namespace is actually defined by multiple headers. Unlike classes, namespaces do not need to be defined in one header; they can be spread over multiple.
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.
I get these error messages for all cout and endl:
main.cc:17:5: error: ‘cout’ was not declared in this scope
main.cc:17:5: note: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: note: ‘std::cout’
After following the suggestion, everything is fine. Now I am curious, why I had to do that. We used C++ in classes before, but I never had to write a std:: before any of those commands. What might be different on this system?
It seems possible your class may have been using pre-standard C++. An easy way to tell, is to look at your old programs and check, do you see:
#include <iostream.h>
or
#include <iostream>
The former is pre-standard, and you'll be able to just say cout as opposed to std::cout without anything additional. You can get the same behavior in standard C++ by adding
using std::cout;
or
using namespace std;
Just one idea, anyway.
In the C++ standard, cout is defined in the std namespace, so you need to either say std::cout or put
using namespace std;
in your code in order to get at it.
However, this was not always the case, and in the past cout was just in the global namespace (or, later on, in both global and std). I would therefore conclude that your classes used an older C++ compiler.
Everything in the Standard Template/Iostream Library resides in namespace std. You've probably used:
using namespace std;
In your classes, and that's why it worked.
You could use the namespace
http://www.daniweb.com/software-development/cpp/threads/109029/what-its-the-use-of-using-namespace-std
But you might offend someone
Why is "using namespace std" considered bad practice?
You probably had using namespace std; before in your code you did in class. That explicitly tells the precompiler to look for the symbols in std, which means you don't need to std::. Though it is good practice to std::cout instead of cout so you explicitly invoke std::cout every time. That way if you are using another library that redefines cout, you still have the std::cout behavior instead of some other custom behavior.
"std" is a namespace used for STL (Standard Template Library). Please refer to https://en.wikipedia.org/wiki/Namespace#Use_in_common_languages
You can either write using namespace std; before using any stl functions, variables or just insert std:: before them.
If you are working in ROOT, you do not even have to write #include<iostream> and using namespace std; simply start from int filename().
This will solve the issue.
I'm using in my code many namespaces including the std one , so when I want to declare a string variable in my code should I precise std::string or I can just put string :
#include <string.h>
using namespace std;
using namespace boost;
using namespace xerces;
int main()
{
/*! should I declare my str like this */
std::string str;
/*! or I can declare it like this */
string str1;
cout << str << str1 <<endl;
return 0;
}
Since you have using namespace std;, the name string means the same as std::string[*]. It's therefore a question of style which you prefer (and if you prefer std::string then you can leave out using namespace std;).
There are some name clashes between std:: and boost::, in particular for things that were trialled in Boost prior to standardization. So for example if you include the appropriate headers then both std::shared_ptr and boost::shared_ptr exist. They may or may not refer to the same type, I haven't checked whether Boost tries to detect the standard type before defining its own.
So it's not necessarily a good idea to use both std and boost namespaces at the same time. You can use individual names with using std::string;, instead of the whole namespace.
[*] if std::string is defined, which it isn't, since you didn't include <string>.
You can just write string. But what if boost or xerces also have a symbol string? I would advise against using these using directives. It is not only string that could clash. You are essentially pulling a whole lot of symbols into the global namespace. If you really want to avoid typing std:: then you can use a typedef:
typedef std::string MyStr;
You can put just string if you use using namespace std;.
Adding using namespace std; may not be the best idea in all cases, because it can lead to conflicts between namespaces in some cases (though unlikey for string).
Usually it is not needed to specify std::string if you have declared using namespace std; BUT as a general case, if there are multiple namespaces which contain different classes with the same name, then you will have to specify the namespace next to the type (namespace::type) regardless of the existence of the using statement.
You are using the namespace std so you do not NEED to prepend string with std:: but you CAN if you want.
A good way to code is not to use any relevant namespace in headers, in order to prevent exposing the namespaces outer when #include. But in compiled source, you can do whatever you want, even using the std namespace and call std::string. Sometimes it's even needed (if you include two namespaces that define the same string class).
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;
}