3

I am new to C++ and am writing a simple program to test out working with strings. I have defined a separate function that returns a string and want to call it within the main method. The same code works within the main method but I need to define it as a separate function.

My code is below:

7 #include <cstdlib>
8 #include <iostream>
9 #include <string>
10 
11 using namespace std;
12 
13 // function declaration
14 string hi();
15 
16 int main(int argc, char** argv) {
17     // call method
18     string hi;
19     hi = hi();
20     cout << hi << endl;
21 }
22 
23 string hi() {
24     //simple string function
25     return "Hello World";
26 }

And below is the error returned to the console when I try to compile with g++:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:19:13: error: no match for call to ‘(std::__cxx11::string {aka std::__cxx11::basic_string<char>}) ()’
 hi = hi();
         ^
1
  • 3
    Simply use different names for the variable and the function. Or qualify the name in the call, like ::hi(). Commented Aug 29, 2016 at 22:54

5 Answers 5

6

You shadow your function declaration with your variable name. You can do 1 of 2 things:

  1. Rename the function or variable. (example)
  2. Qualify the name in the call, this would involve invoking the namespace of the function (ie. the global namespace) like this: ::hi(). (example)
Sign up to request clarification or add additional context in comments.

Comments

5

Problem in the Code

You named the variable name and the function name, both hi, so the compiler gets confused about which one you mean.

Solution 1

As @Cheersandhth said, do this:

hi = ::hi();

to get the global hi in its global namespace, which is the function.

Live Example


Solution 2


Otherwise, if you want to change the variable name, you could either change the function name, or the variable, to a different value, and then it would work. Here is an example:

int main(int argc, char** argv)
{
    string l_hi;
    l_hi = hi();
    cout << l_hi;
}

Or the alternative:

int main(int argc, char** argv)
{
    string hi;
    hi = hello();
    cout << hi;
} 
string hello() 
{
    return "Hello, World!";
}

Both of these solutions would work, the one you want to use would be a matter of preference. Also, use this answer as advice to not do name shadowing, which could either lead the compiler into picking one of the two names, (provided they fit the right context), or an error may be thrown.


Solution 3

Wait, there's a third solution?

Yes, but solution three is more of a workaround, although I prefer it. Just get rid of the variable itself, and cout like this:

cout << hi(); //So simple!

1 Comment

Oh, yes, sorry for the mistake, typo is fixed, @owacoder
1

I believe the error message is rather clear: the hi in main hides the global hi-function. Use another name somewhere or scope the function: hi = hi() => hi = ::hi();

Comments

1

Try

 string hi();

 int main(int argc, char** argv) {
     string _hi;
     _hi = hi();
     cout << hi << endl;
 }

 string hi() {
     return "Hello World";
 }

Comments

1

The reason the compiler is throwing an error is because it is parsing the parentheses after hi as a function call. But the string class in C++ doesn't have a function call operator member function. So, it gets confused when it sees hi() because it thinks you are talking about the string hi variable you just declared on the previous line. So, to distinguish the hi variable from the hi() function that returns a string, you can do one or both of the following:

  1. You can rename your locally declared string variable to something that doesn't match the global function or vice versa.
  2. You can prefix the function call with the global namespace qualifier to tell the compiler that you are using the global hi() function. (ie. ::hi()).

Example of first:

#include <iostream>
#include <string>
using namespace std;
string hi();
int main(int argc, char** argv) {
    string my_hi;
    my_hi = hi();
    cout << my_hi << endl;
    return 0;
}
string hi() {
    return "Hello, world!";
}

Example of second:

#include <iostream>
#include <string>
using namespace std;
string hi();
int main(int argc, char** argv) {
    string hi;
    hi = ::hi();
    cout << hi << endl;
    return 0;
}
string hi() {
    return "Hello, world!";
}

Because classes can overload the function call operator, it can sometimes look like you are calling a normal function, but the compiler may be calling the function call operator. Good naming practices can help minimize these issues, but sometimes you may need to be specific and include the global namespace qualifier to clarify to the compiler what you mean (ie. If the string class had a function call operator defined, there would be no compiler error, but you would not get the answer you wanted).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.