Declaring strings as std:string in C++

2019-02-20 00:03发布

问题:

This is based on GCC/G++ and usually on Ubuntu.

Here's my sample program I've done:

#include <iostream>

using namespace std;

int main()
{

std::string c = "Test";
cout << c;
return 0;
}

The above code works fine.

But I have two issues that I don't quite get...

  1. Writing the string declaration as std:string also works fine. What's the difference.

  2. If I use this std::string within a class to declare a private variable, I get an error error: ‘std’ does not name a type. Example of this declaration:

class KType
{
private:
  std:string N;

Can someone please explain these issues? Many thanks!

回答1:

Writing the string declaration as std:string also works fine. What's the difference.

The difference would be slight clearer if you formatted it differently:

std:
    string c = "Test";

You're declaring a label called std, and using the name string which has been dumped into the global namespace by using namespace std;. Writing it correctly as std::string, you're using the name string from the std namespace.

If I use this std::string within a class to declare a private variable, I get an error error: ‘std’ does not name a type.

That's because you can't put a label in a class definition, only in a code block. You'll have to write it correctly as std::string there. (If the class is defined in a header, then using namespace std is an even worse idea than in a source file, so I urge you not to do that.)

Also, if you're using std::string, then you should #include <string>. It looks like your code works by accident due to <iostream> pulling in more definitions than it need to, but you can't portably rely on that.



回答2:

You need to include the string class header:

#include <string>

This code has a typo, missing a second colon

std:string N;

should be:

std::string N;

With a single colon, it becomes a label for goto, which is probably not what you meant.



回答3:

First problem:

First of all, you are missing the #include <string> directive. You cannot rely on other headers (such as <iostream>) to #include the <string> header automatically. Apart from this:

Second problem:

Writing the string declaration as std:string also works fine. What's the difference.

That is because you have an (evil) using directive at global namespace scope:

using namespace std;

The effect of this directive is that all names from the std namespace are imported into the global namespace. This is why the fully-qualified std::string and the unqualified string resolve to the same type.

If you omitted that using namespace std; directive, you would get a compiler error when using the unqualified string name.

Third problem:

If I use this std::string within a class to declare a private variable, I get an error error: ‘std’ does not name a type. Example of this declaration:

You are missing a colon. That should be:

std::string
//  ^

And not

std:string
// ^


回答4:

Writing the string declaration as std:string also works fine. What's the difference.

There is no difference, unless you declare something else called string. In your code, string and std::string refer to the same type. But avoid using namespace std at all cost.

If I use this std::string within a class to declare a private variable, I get an error error: ‘std’ does not name a type. Example of this declaration:

You need to #include <string> in order to use std::string. What is happening is that in your first code sample, <iostream> seems to be including <string>. You cannot rely on that. You must include <string>.