Why is operator""s hidden in a namespace? - c++

In order to use operator""s for std::string you have to do using namespace std::string_literals. But user-defined literals that don't begin with _ are reserved, so possible conflict can't be an excuse. The other operator""s is from std::chrono but that's for int literals, so there's no conflict there either.
What's the reason for this?

There are actually two reasons why literals are put into namespaces:
It is considered undesirable that users would use using namespace std; just to get hold of the corresponding literals. Having the literals declared in namespaces specific to these doesn't cause the problem.
Depending on the domain it may be desirable to use s as the suffix for something else. There is already another suffix s to mean seconds but they don't really conflict.
In the video of STL's CppCon 2014 talk (posted by remyable in a comment) Stephan T. Lavavej explains the overall design of the literals in C++14 and its pretty clear that they are not supposed to be in the global namespace! Instead, the literal suffixes in the standard library live in a hierarchy of inline namespaces giving users fine-grained control over the literals being made available. For example, the literal suffix for strings is declared like this (21.3 [string.classes] paragraph 1):
namespace std {
inline namespace literals {
inline namespace string_literals {
string operator"" s(char const* str, size_t len);
}
}
}
This hierarchy of inline namespaces makes it possible for users to get the appropriate choice of literal suffixes:
using namespace std; - you get everything in the standard C++ library, including the literal suffixes, without any qualification.
using namespace std::literals; - you get all literal suffixes defined in the standard C++ library.
using namespace std::string_literals; - you get all literal suffixes applicable to strings.
using namespace std::literals::string_literals; - yes, you can do that but you really shouldn't: that's equivalent to using namespace std::string_literals;.
Clearly, the committee wouldn't have gone to that much effort if it had considered the idea viable to just pollute the global namespace with literal suffixes, although they can't even conflict with any user literal suffixes.

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.

Clion cannot resolve i after integer when <complex> library is included [duplicate]

In order to use operator""s for std::string you have to do using namespace std::string_literals. But user-defined literals that don't begin with _ are reserved, so possible conflict can't be an excuse. The other operator""s is from std::chrono but that's for int literals, so there's no conflict there either.
What's the reason for this?
There are actually two reasons why literals are put into namespaces:
It is considered undesirable that users would use using namespace std; just to get hold of the corresponding literals. Having the literals declared in namespaces specific to these doesn't cause the problem.
Depending on the domain it may be desirable to use s as the suffix for something else. There is already another suffix s to mean seconds but they don't really conflict.
In the video of STL's CppCon 2014 talk (posted by remyable in a comment) Stephan T. Lavavej explains the overall design of the literals in C++14 and its pretty clear that they are not supposed to be in the global namespace! Instead, the literal suffixes in the standard library live in a hierarchy of inline namespaces giving users fine-grained control over the literals being made available. For example, the literal suffix for strings is declared like this (21.3 [string.classes] paragraph 1):
namespace std {
inline namespace literals {
inline namespace string_literals {
string operator"" s(char const* str, size_t len);
}
}
}
This hierarchy of inline namespaces makes it possible for users to get the appropriate choice of literal suffixes:
using namespace std; - you get everything in the standard C++ library, including the literal suffixes, without any qualification.
using namespace std::literals; - you get all literal suffixes defined in the standard C++ library.
using namespace std::string_literals; - you get all literal suffixes applicable to strings.
using namespace std::literals::string_literals; - yes, you can do that but you really shouldn't: that's equivalent to using namespace std::string_literals;.
Clearly, the committee wouldn't have gone to that much effort if it had considered the idea viable to just pollute the global namespace with literal suffixes, although they can't even conflict with any user literal suffixes.

Why aren't C++14 standard-defined literals in the global namespace by default?

C++14 includes standard-defined literals for, amongst other things, std::string and various timespans from the <chrono> header.
To use them you must say using namespace std::literals; (or some variation depending on exactly which literals you want, as they're in a variety of inline namespaces).
All this is good, but I'm curious as to why the using declaration is required. UDLs without a leading underscore are reserved for the implementation, so there is no possibility that "hello world"s could ever mean anything else in a standard-conforming programme.
So why isn't #include <string> sufficient to bring the literal conversion function into scope? Why must I explicitly include the literal namespace?
EDIT: N3531 is the most recent version of the proposal I could find -- unfortunately it doesn't discuss the motivation for putting things in a namespace but only says:
One can summarize the requirements of the [Portland] discussion as follows:
use an inline namespace for a (group of related) UDL operator(s)
There already are two UDLs named s: one for strings and one for seconds. Due to the understandably terse names of suffixes, they chronically suffer from name conflicts, so pouring all of them into one namespace cannot go well for long. Hence it was decided that they be put into inline namespaces, which allow for both unambiguous (using namespace std::literals::chrono_literals) and simple using directives (using namespace std).
the standard library already defines multiple versions of what s can mean:
It can be used to define a string literal.
It can be used to define a chrono::seconds literal.
One is based on a string literal, one is based on an integer or a double literal, of course, i.e., they can actually coexist. However, I'd expect that there may be more uses of s in the future. Thus, having to choose which namespaces are imported rather than getting any imposed on you seems like a reasonable approach.
Look at paper N2765. UDLs are hooked into the regular name lookup process. As string literals have common string types, there's a large chance of a collision if you ignored namespaces.

std::string vs string

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