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.
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.
There's recommendation in C++ community to not to use using namespace std;. But suppose you want to use string literals e.g. auto s = "dummy"s;.
Not using using namespace std; cause to failed compile. What is the solution?
operator""s is in 2 inlined namespaces in namespace std. It basically looks like this:
namespace std
{
inline namespace literals
{
inline namespace string_literals
{
//operator""s implementation
//...
}
}
}
So, to only get the string literals, use using namespace std::string_literals;.
Alternatevely, if you want to include every literal - including the string literals (like s for seconds if you include chrono, ...): using namespace std::literals;.
Depending on the situation, you might also consider using:
using std::string_literals::operator""s;
instead of importing every name from that namespace.
Note that you should still not include it in a header, at global level
(but you can do it inside inline or member functions or namespaces you control)
For string literals you can use:
using namespace std::string_literals;
That will pull about 4 names into the namespace which is fine. But when you do:
using namespace std;
Then you pull in thousands of names, many of which are commonly used in programs like count and time. This can create hard to find bugs from accidentally referring to the wrong thing.
That's not an issue with the string literals.
Also none of the names that using namespace std::string_literals; brings in should interfere with user defined names because user defined string literals must begin with _ (according to the standard) which avoids conflicts.
However you should still avoid using namespace std::string_literals; in the global namespace of a header file because you should not impose any feature on a user that they don't request.
Above operators are declared in the namespace std::literals::string_literals, where both literals and string_literals are inline namespaces. Access to these operators can be gained with using namespace std::literals, using namespace std::string_literals, and using namespace std::literals::string_literals
Source : std::literals::string_literals::operator""s
I would add the "using namespace" thing inside my block of code:
auto get_greetings()
{
using namespace std::string_literals;
return "Hello world"s;
}
So, the probability of having operator""s overloaded in some library should be ZERO, because the standard suggests we ordinary people should add a suffix with an underscore.
And, since I am adding this using namespace inside my function, no probability of name clashes will occur outside it.
I am using the OpenCV library for my project and using namespace "cv" and "std" for my source files.I want to use the string split function to split a string based on a delimiter .But the "split" function is defaulting to the namespace "cv" and is showing errors related to wrong arguments as it is expecting arguments related to the OpenCV slpit function.
What can be done to overcome this problem?I see that the same function worked fine in another source file even though that one has got both std and cv anmespace.
These are the headers I am including in both files -
#include "stdafx.h"
#include <unordered_map>
#include <iostream> // for standard I/O
#include <fstream>
#include <string> // for strings
#include <iomanip> // for controlling float print precision
#include <sstream> // string to number conversion
Avoid putting using namespace std; and using namespace cv; in your code, especially in headers.
If you can't stop yourself, fully qualify the function where you need to, e.g.
std::split(...)
As long as the argument sets for the cv and std functions are disjoint, you shouldn't introduce any ambiguity in the overload resolution (both would be injected into the global namespace).
Based on a comment showing split is from a 2013 proposal much more likely is that your compiler just doesn't implement std::split yet.
All you need to do is prefix the function with its' namespace
For instance
std::split(...);
You can overcome this by using explicit namespace specifiers.
std::split
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 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.