tags:

views:

871

answers:

7

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.

+9  A: 

It considers

string strA();

as a function declaration.

For default constructor use:

string strA;
Cătălin Pitiș
You may use that notation when allocating off the heap:string* strA = new string();
Skilldrick
+4  A: 

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;
anon
A: 

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)

Naveen
+21  A: 

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

Tadeusz Kopec
And this is one reason why I stopped using C++.
Dietrich Epp
+3  A: 

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

laalto
Only if the pointer to function is non-null. Anyway, a pointer to function should point to its definition, and that's missing here. This shouldn't have linked.
MSalters
+2  A: 

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

MSalters
Type of strA is a function. std::string(void) . It's not a function pointer. He would have to declare it as string (*strA)(); if he wanted it to be a function pointer. I probably know what you meant, but your last sentences sound like you say it's a function pointer.
Johannes Schaub - litb
+4  A: 

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.

Johannes Schaub - litb