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.
Related
If name in C++ is not fully qualified, e.g. std::cout, it can lead to an unintentional error, such as mentioned at https://en.cppreference.com/w/cpp/language/qualified_lookup. But using a fully qualified name for ::std namespace, e.q. ::std::cout, is very rare, as I have noticed.
Is there any reason why a fully qualified name for ::std namespace is not used?
And what about using fully qualified name for own created namespaces? Is it good idea?
You are completely right, in the sense that yyyy::xxx can be ambiguous if there is a namespace yyyy and also a class yyyy which are both visible in the same scope. In this case only the full qualification ::yyyy::xxx can solve the ambiguity. The example of your link makes it very clear:
// from cppreference.com
#include <iostream>
int main() {
struct std{};
std::cout << "fail\n"; // Error: unqualified lookup for 'std' finds the struct
::std::cout << "ok\n"; // OK: ::std finds the namespace std
}
But in practice, it's difficult to create a conflicting std at top level, since most of the includes from the standard library will make it fail:
#include <iostream>
struct std { // OUCH: error: ‘struct std’ redeclared as different kind of symbol
int hello;
};
This means that to create a conflict, you'd need to define local classes or introduce a using clause in another namespace. In addition, nobody will (dare to) call a class std.
Finally, in practice, ::yyyy::xxx is less convenient to read. All this explains why you won't find it very often.
Additional remark
The problem is not so much for std which is well known, but rather for your own namespaces and third party libraries. In this case, the namespace alias would be a better alternative to :::yyyy to disambiguate:
namespace foo {
void printf() { }
}
int main() {
foo::printf(); // ok, namespace is chose because no ambiguity
struct foo {/*...*/ }; // creates ambiguity
//foo::printf(); // error because struct foo is chosen by name lookup
::foo::printf(); // ok, but not if you decide to move the code to be nested in another namespace
namespace mylib = foo ; // or ::foo (see discussion below)
mylib::printf(); // full flexibility :-)
}
Its advantage is a higher flexibility. Suppose for example that you'd move your code to nest it in an enclosing namespace. With the namespace alias, your code could continue to work as is (in the worst case with a minor adjustment in the alias definition). With the global scope resolution, you'd have to change all the statements where the global namespace ::foo would be used.
To maintain big code or better readability or clashes in names, C++ has provided namespace " a declarative region".
A namespace definition can appear only at global scope, or nested within another namespace.
#Sample Code
#include <iostream>
int main()
{
struct std{};
std::cout << "fail\n"; // Error: unqualified lookup for 'std' finds the struct
::std::cout << "ok\n"; // OK: ::std finds the namespace std
}
In the above code compiler is looking for cout in struct std , but in next line when you use ::std::cout it looks for cout in globally defined std class.
Solution:
#include <iostream>
//using namespace std; // using keyword allows you to import an entire namespace at once.
namespace test
{
void cout(std::string str)
{
::std::cout<<str;
}
}
int main()
{
cout("Hello");//'cout' was not declared in this scope
::test::cout("Helloo ") ;
::std::cout<<"it is also ok\n";
}
Or use the in this way , it is just for better readability
##
using namespace test;
int main()
{
cout("Hello");//'cout' was not declared in this scope
cout("Helloo ") ;
::std::cout<<"it is also ok\n";
}
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.
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.
This question already has answers here:
Is using namespace in an anonymous namespace safe?
(2 answers)
Closed 3 months ago.
I want using namespace std; to apply to classes as well as functions without polluting the global namespace, but I'm wondering if it's an ok approach.
namespace
{
using namespace std;
class S
{
public:
S()
{
cout << "ok";
}
friend ostream operator<<(ostream& os, const S& s);
};
}
Any caveats to this?
It will work but keep in mind the following points:
You should limit its use in a source file, not in a header file (in general you should refrain from using unnamed namespaces in headers since they can easily mess around with your symbol definitions, especially if there are inline functions that use something from the anonymous namespace).
It's a bad practice and adding an additional naming hierarchy layer (i.e. the anonymous namespace) just for laziness is as bad as it sounds.
If it's in header file then it's not preferable as this file could be included in multiple source file. If in some source file then its acceptable
Whilst this looked like a great solution, in my experiments it doesn't do as I expected it would. It doesn't limit the scope of the using directive.
Consider this:
#include <string>
namespace {
string s1; // compile error
}
namespace {
string s2; // compile error
}
string s3; // compile error
int main()
{
}
None of those strings compile because they are not properly qualified. This is what we expect.
Then consider this:
#include <string>
namespace {
using namespace std;
string s1; // compiles fine (as expected)
}
namespace {
string t2; // compiles fine (I didn't expect that)
}
string v3; // compiles fine (I didn't expect that either)
int main()
{
}
So placing a using directive within an unnamed namespace appears to be exactly the same as placing it in the global namespace.
EDIT: Actually, placing a symbol in an unnamed namespace makes it local to the translation unit. So this is why it can't work for the intended purpose.
Therefore it has to be a no-no for headers.
An unnamed namespace doesn't contain the effects of a using-directive:
namespace A {int i;}
namespace {
using namespace A;
}
int j=i,k=::i; // OK
Both qualified and unqualified lookup follow the implicit using-directive for the unnamed namespace and then follow the explicit one within it. Wrapping the unnamed namespace inside another namespace limits the unqualified case to other code within that outer namespace, of course:
namespace A {int i;}
namespace B {
namespace {
using namespace A;
}
int j=i; // OK, as above
}
int j=i, // error: i not found
k=B::i; // OK
However, in either case you might as well write the using-directive outside the unnamed namespace (or not write it at all if it would be problematic, perhaps because it would appear in a header file).
Don't take the decision to use an anonymous namespace just so you can limit the scope of a using directive.
That being said, if an anonymous (or any other) namespace is already there and you want the advantages of the using inside it, it's fine as long as your coding standards okay it.
I don't suppose anyone tell me whats the difference between using the std::string and just the string data type in C++??
In what situation should the std::string should be used over the standard string??
Thanks.
They're both the same type. std::string specifies the namespace, while string only makes sense if a using namespace std; or using std::string statement is used. So it doesn't make any difference what you use (as long as you're consistent).
If you're talking about the string literals (such as "hello"), then they're of type const char [], that implicitly decays in a const char *. std::string has a non-explicit constructor that takes a const char *, this allowing implicit conversion from const char * to std::string. The opposite operation can be done with the std::string::c_str() method.
If you're looking for a reason to use std::string instead of const char *, then I guess my answer would be "as much as you can".
These are likely the same thing within your program. The "standard" string resides within the "std" namespace. If you are "using std::string;" or "using namespace std;" within the module, then they are equivalent. If you aren't specifying a "using" statement, then you are required to provide the namespace of the object. It's preferable to not provide "using" statements within the header file and therefore you will typically see namespace resolution/specifiers on objects. (i.e. std::vector, mynamespace::myclass, etc.). The use of "using" is more common in implementation files where they won't affect other files as they would if specified in a header file.
It's possible to use a string object from another provider. In this case the provider would/should have their string object implementation in their own namespace and you would need to declare which string object you were using.
So:
File: stdString.cpp
-------------
#include <string>
#include "providerx/string.h"
using namespace std;
void foo()
{
string x; // Using string object provided by the C++ standard library
std::string y; // Again, using C++ standard lib string
providerx::string // Using string object defined within the providerx namespace
}
File: providerString.cpp
-------------------
#include "providerx/string.h"
using providerX::string;
void foo()
{
string x; // Using providerx string object
}
Most likely, you have using namespace std somewhere in your code. This is allowing you to access members of the std namespace without resolving the scope. Therefore...
std::string == string