在main方法中调用返回String的函数



我是c++的新手,正在编写一个简单的程序来测试如何处理字符串。我定义了一个单独的函数,它返回一个字符串,并希望在main方法中调用它。相同的代码在main方法中工作,但我需要将其定义为一个单独的函数。

我的代码如下:

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 }

下面是当我尝试用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. 重命名函数或变量。(例子)
  2. 限定调用中的名称,这将涉及调用函数的名称空间(即。全局命名空间),如下所示:::hi()。(例子)

代码中的问题

您将变量名和函数名命名为hi,因此编译器会混淆您指的是哪个。

解决方案1

正如@Cheersandhth所说,这样做:

hi = ::hi();

获取全局命名空间中的全局hi,即函数。

<

生活例子/kbd>


解决方案2


否则,如果您想更改变量名,您可以将函数名或变量更改为不同的值,然后就可以工作了。下面是一个例子:

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

或替代:

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

这两种解决方案都可以,您想使用哪一种解决方案取决于您的偏好。另外,使用这个答案作为不要使用名称遮蔽的建议,这可能会导致编译器选择两个名称中的一个(如果它们适合正确的上下文),或者可能会抛出错误。


3

解决方案

等等,还有第三种解决方法吗?

是的,但是解决方案三更像是一种变通方法,尽管我更喜欢它。只要去掉变量本身,然后像这样添加cout:

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

我认为错误消息相当清楚:main中的hi隐藏了全局的hi函数。在某个地方使用另一个名称或作用域:hi = hi() => hi =::hi();

Try

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

编译器抛出错误的原因是因为它将hi后面的括号解析为函数调用。但是c++中的string类没有函数调用操作符成员函数。所以,当它看到hi()时,它会感到困惑,因为它认为你在谈论你刚刚在前一行声明的string hi变量。因此,要将hi变量与返回stringhi()函数区分开来,您可以执行以下一项或两项操作:

  1. 您可以将本地声明的string变量重命名为与全局函数不匹配的东西,反之亦然。
  2. 你可以用全局命名空间限定符作为函数调用的前缀,告诉编译器你正在使用全局hi()函数。(即。::hi())。

第一个例子:

#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!";
}

秒的例子:

#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!";
}

因为类可以重载函数调用操作符,所以有时看起来像在调用普通函数,但编译器可能正在调用函数调用操作符。良好的命名实践可以帮助最小化这些问题,但有时您可能需要具体一些,并包括全局名称空间限定符,以便向编译器澄清您的意思。如果string类定义了函数调用操作符,则不会出现编译错误,但您将无法得到想要的答案)。

最新更新