std::string vs string - c++

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).

Related

Can't use string literal "s" with a string in C++ [duplicate]

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.

Using string literals without using namespace std

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.

Using a header file instead of the standard namespace

I am curious if there is any header file in C++ which can be used (included) instead of the standard namespace (namespace std) that works the same even in new versions of C++? I want to know if I can write code without using any namespaces and still be able to use the string data type.
string is in the std namespace, so you can't completely disregard it.
There are options though:
using std::string;
using namespace std;
typedef std::string myString;
//or fully qualify the name
std::string mystr;
which you can put in a header and include that.
There, now I gave you the recipe for disaster. Don't use it!
Namespaces are good. Learn to use them, rather than hacking your way around them.
Headers and namespaces are not related, and namespaces are good things. using namespace std is bad. You can always use the std::string data type without using namespace std;.
To use "using namespace std;" is a poor idea (although I have to admit I do this rather regularly in my samples I post here, for ease of typing). To hide the same in a header file is an even worse idea.
Namespaces are there for a reason.
But if you have, say, 100000 lines of already existing code that is written pre-namespace standard, and you quickly want to port that to use in a new compiler, then adding "using namespace std;" to the top of each file would be the preferred solution.
You could typedef the classes you wish to use, but this is a really bad idea.
#include <string>
typedef std::string string;

C++ name space confusion - std:: vs :: vs no prefix on a call to tolower?

Why is this?
transform(theWord.begin(), theWord.end(), theWord.begin(), std::tolower); - does not work
transform(theWord.begin(), theWord.end(), theWord.begin(), tolower); - does not work
but
transform(theWord.begin(), theWord.end(), theWord.begin(), ::tolower); - does work
theWord is a string. I am using namespace std;
Why does it work with the prefix :: and not the with the std:: or with nothing?
thanks for your help.
using namespace std; instructs the compiler to search for undecorated names (ie, ones without ::s) in std as well as the root namespace. Now, the tolower you're looking at is part of the C library, and thus in the root namespace, which is always on the search path, but can also be explicitly referenced with ::tolower.
There's also a std::tolower however, which takes two parameters. When you have using namespace std; and attempt to use tolower, the compiler doesn't know which one you mean, and so it' becomes an error.
As such, you need to use ::tolower to specify you want the one in the root namespace.
This, incidentally, is an example why using namespace std; can be a bad idea. There's enough random stuff in std (and C++0x adds more!) that it's quite likely that name collisions can occur. I would recommend you not use using namespace std;, and rather explicitly use, e.g. using std::transform; specifically.

C++ error: ‘string’ has not been declared

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.