George
George

Reputation: 15561

C++ empty String constructor

I am a C++ beginner, so sorry if the question is too basic.

I have tried to collect the string constrcturs and try all them out (to remember them).

string strA();          // string(); empty string // incorrect
string strB("Hello");   // string( const char* str)
string strC("Hello",3); // string( const char* str, size_type length)
string strD(2,'c');     // string( size_type lenght, const char &c)
string strE(strB);      // string( const string& s)

cout << strA << endl;
cout << strB << endl;
cout << strC << endl;
cout << strD << endl;
cout << strE << endl;

All of them works except for the strA. It prints "1". Why? Whats the type of the strA in this case? How can I check the type of stuff when I am unsure?

I have noticed that the correct way is this (which by the way seems to be inconsistent with the other constructors, sometimes parens sometimes no parens):

string strA;

ps: question in bold, usual irrelevant answers will be downvoted.

Upvotes: 16

Views: 31273

Answers (7)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507313

I don't think that in this case, the rule "if it could be a declaration, it's taken to be a declaration" applies. Since in the following, both things are declarations

string a;
string a();

The one is the declaration of an object, and the other is the declaration of a function. The rule applies in other cases. For example, in this case:

string a(string());

In that case, string() can mean two things.

  • Declaration of an unnamed function parameter
  • Expression creating a default constructed string

The fule applies here, and string() is taken to mean the same as the following, named parameter (names are irrelevant in parameters when declaring a function)

string a(string im_not_relevant());

If a function takes as parameter an array or another function, that parameter decays into a pointer. In case of a function parameter, to a pointer to the function. Thus, it is equivalent to the following, which may look more familiar

string a(string (*im_not_relevant)());

But in your case, it's rather the syntax that's getting into the way. It's saying that the following is a function declaration. It can never be the declaration of an object (even though that was probably intended by the programmer!)

string a();

So there is no ambiguity in this context in the first place, and thus it declares a function. Since string has a user defined constructor, you can just omit the parentheses, and the effect remains the same as what was intended.

Upvotes: 4

MSalters
MSalters

Reputation: 180225

tkopec is right on why it doesn't work. To answer your second question, here's how you check the type:

template<typename TEST> void Error_() {
   TEST* MakeError = 1;
}

By calling Error_(StrA); you will get a compile error, and your compiler will probably tell you that it happened in Error_< std::basic_string<char, std::allocator<char> > (*)(void)>(std::basic_string<char, std::allocator<char> > (*)(void)) Now, std::basic_string > is just std::string, so this really means Error_< std::string (*)(void)> (std::string (*)(void)). The part between '<>' is repeated between '()', and that's the sype of strA. In this case, std::string (*)(void).

Upvotes: 2

laalto
laalto

Reputation: 152917

It prints 1 because pointers to functions are always converted to numeric as true.

Upvotes: 3

Tadeusz Kopec for Ukraine
Tadeusz Kopec for Ukraine

Reputation: 12413

This is a very popular gotcha. C++ grammar is ambiguous. One of the rules to resolve ambiguities is "if something looks like declaration it is a declaration". In this case instead of defining a variable you declared a function prototype.

string strA();

is equivalent to

string strA(void);

a prototype of a no-arg function which returns string.

If you wish to explicitly call no-arg constructor try this:

string strA=string();

It isn't fully equivalent - it means 'create a temporary string using no-arg constructor and then copy it to initialize variable strA', but the compiler is allowed to optimize it and omit copying.

EDIT: Here is an appropriate item in C++ FAQ Lite

Upvotes: 32

Naveen
Naveen

Reputation: 73503

Compiler interprets string strA() as a function prototype of a function which takes void arguments and returns an object of string type. If you want to create a empty string object use string strA; (without paranthesis)

Upvotes: 1

anon
anon

Reputation:

In C++, as in C, there is a rule that says that anything that looks like a declarartion will be treated as a declaration.

string strA();

looks like a function declaration, so it is treated as one. You need:

string strA;

Upvotes: 6

Cătălin Pitiș
Cătălin Pitiș

Reputation: 14317

It considers

string strA();

as a function declaration.

For default constructor use:

string strA;

Upvotes: 14

Related Questions