当前位置:  开发笔记 > 编程语言 > 正文

函数调用缺少参数列表警告

如何解决《函数调用缺少参数列表警告》经验,为你挑选了2个好方法。

我正在阅读"C++编程语言 - 第四版",我正在打一个简单的练习,只是为了获得C++语法,我不小心偶然发现了让我挑眉的东西.总之,我忘了补充()accept主:

bool accept()
{
    cout << "Do you want to proceed (y or n)?\n";

    char answer = 0;
    cin >> answer;

    if (answer == 'y')
    {
        return true;
    }
    return false;

}

int main()
{
    accept;
}

这运行并编译并生成(在VS2015中)a

C4551 - 函数调用缺少参数列表

我发现自己在阅读lambda和一些关于SO的问题应该被关闭,因为他们主要是要求"调试我的代码".

我想如果代码编译并运行,并且该函数包含一个阻塞语句(等待用户输入)和一个返回类型,那么所有代码​​都将按预期执行,而不管是否遗漏了括号; 但事实并非如此.

另外,我想我会将调用更改为acceptmain,以bool a = accept; cout << a;尝试阻止任何优化(如果那是实际发生的事情),并且也没有调用accept()代码.

我很想知道的是:

    accept要编译成什么叫?

    为什么不accept调用代码

    为什么这只是一个警告,而不是错误(我知道我可以更改配置以将其显示为错误,当实际结果与预期结果不同时,我更加如此质疑这是如何被接受的语法所以"显着?"这问题可能是基于意见的,如果你同意,可以省略.)

    bool a = accept; cout << a;在main中运行代码生成1输出.这是什么时候false是默认的bool值(至少在C#中)并且没有什么可以返回真值,因为接受代码没有被执行?

Nicol Bolas.. 13

    没有"打电话accept".见#3.

    因为#1.

    使用没有函数调用语法的函数名称(即:)()意味着您正在访问函数本身.例如,您可以将其存储在函数指针中(通过函数到指针衰减):

    using my_func = bool(*)(); //Function that takes nothing and returns a bool.
    my_func var = accept; //Store a pointer to `accept`.
    

    然后你可以发出var();,这会打电话accept.

    但是,因为你从不存储函数,编译器猜测你可能打算调用函数,而不是访问函数的指针.accept;但是是一个合法的C++语句,因此编译器不能对它进行错误.它可以发出警告,因为语句没有任何结果,你可能打算调用该函数.这与以下陈述没有什么不同1;:完全合法,但完全没用.

    这样做是因为C++技巧.非空指针衰减到布尔值true.并accept衰减到一个非null的函数指针.因此,当转换为a时bool,它将是true.你还没有调用这个函数.


templatetype.. 8

在C++中,任何以分号后跟的表达式都是合法的陈述.(为什么?因为C让你这样做,我想).这意味着以下所有内容都是法律声明:

 5;
 3 + 5;
 1 % 2 == 0;

此形式的语句的效果是表达式被计算然后被丢弃.一个好的优化编译器会消除这里的所有逻辑,因为这些都没有任何副作用.

在你的情况下,写作

accept;

是一个法律声明,因为它accept是一个表达式,用于评估对函数的引用accept.这意味着,accept;声明意味着"评估地址accept,然后丢弃它".这里没有调用函数的原因是函数名本身不调用函数; 你需要括号(函数调用运算符)来实际调用.例如,如果要将函数传递给另一个函数,这很有用.例如,您可能希望将比较函数传递给std::sort,如下所示:

std::sort(range.begin(), range.end(), nameOfMyComparisonFunction)

在这里,如果尝试调用它将是一个真正的问题nameOfMyComparisonFunction,因为在排序例程开始之前无法知道参数.

那为什么这是警告而不是错误?嗯,这是完全合法的C++代码,因此编译器不能顺从地将其称为错误.但是,编译器将其标记为警告是正确的,因为它几乎肯定意味着您犯了错误.也就是说,大多数编译器都有一些设置会将警告报告为错误,如果你将警告级别提高到足够高,编译器可能说"这太可疑了,我会假设你搞砸了什么."

至于你的最后一个 - 为什么呢

bool a = accept;

最终设置atrue?In C++,任何非空指针都会隐式转换为true,任何空指针都会隐式转换为false.在C++中,函数可以隐式转换为指向自身的指针,因此在这种情况下accept求值为accept函数的地址,该函数的地址为非null,因此设置atrue.然后当你写

cout << a << endl;

的值被打印为1,因为bool值被打印为1和0,而不是truefalse默认.那就是说,你可以写

cout << boolalpha << a << endl;

你会看到true打印而已.

希望这可以帮助!



1> Nicol Bolas..:

    没有"打电话accept".见#3.

    因为#1.

    使用没有函数调用语法的函数名称(即:)()意味着您正在访问函数本身.例如,您可以将其存储在函数指针中(通过函数到指针衰减):

    using my_func = bool(*)(); //Function that takes nothing and returns a bool.
    my_func var = accept; //Store a pointer to `accept`.
    

    然后你可以发出var();,这会打电话accept.

    但是,因为你从不存储函数,编译器猜测你可能打算调用函数,而不是访问函数的指针.accept;但是是一个合法的C++语句,因此编译器不能对它进行错误.它可以发出警告,因为语句没有任何结果,你可能打算调用该函数.这与以下陈述没有什么不同1;:完全合法,但完全没用.

    这样做是因为C++技巧.非空指针衰减到布尔值true.并accept衰减到一个非null的函数指针.因此,当转换为a时bool,它将是true.你还没有调用这个函数.



2> templatetype..:

在C++中,任何以分号后跟的表达式都是合法的陈述.(为什么?因为C让你这样做,我想).这意味着以下所有内容都是法律声明:

 5;
 3 + 5;
 1 % 2 == 0;

此形式的语句的效果是表达式被计算然后被丢弃.一个好的优化编译器会消除这里的所有逻辑,因为这些都没有任何副作用.

在你的情况下,写作

accept;

是一个法律声明,因为它accept是一个表达式,用于评估对函数的引用accept.这意味着,accept;声明意味着"评估地址accept,然后丢弃它".这里没有调用函数的原因是函数名本身不调用函数; 你需要括号(函数调用运算符)来实际调用.例如,如果要将函数传递给另一个函数,这很有用.例如,您可能希望将比较函数传递给std::sort,如下所示:

std::sort(range.begin(), range.end(), nameOfMyComparisonFunction)

在这里,如果尝试调用它将是一个真正的问题nameOfMyComparisonFunction,因为在排序例程开始之前无法知道参数.

那为什么这是警告而不是错误?嗯,这是完全合法的C++代码,因此编译器不能顺从地将其称为错误.但是,编译器将其标记为警告是正确的,因为它几乎肯定意味着您犯了错误.也就是说,大多数编译器都有一些设置会将警告报告为错误,如果你将警告级别提高到足够高,编译器可能说"这太可疑了,我会假设你搞砸了什么."

至于你的最后一个 - 为什么呢

bool a = accept;

最终设置atrue?In C++,任何非空指针都会隐式转换为true,任何空指针都会隐式转换为false.在C++中,函数可以隐式转换为指向自身的指针,因此在这种情况下accept求值为accept函数的地址,该函数的地址为非null,因此设置atrue.然后当你写

cout << a << endl;

的值被打印为1,因为bool值被打印为1和0,而不是truefalse默认.那就是说,你可以写

cout << boolalpha << a << endl;

你会看到true打印而已.

希望这可以帮助!

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有