小发现: C/C++函数形参名可加括号

  有一次我发现下面这段代码无法通过编译。

#include <iostream>
using namespace std;

struct A
{
    A(int n) {}
};

struct B
{
    B(A a) {}

    int foo() const
    {
        return 1;
    }
};

int main()
{
    int n = 1;
    B b(A(n));

    cout << b.foo() << endl;
}

  错误信息如下。

  错误信息显示b是一个非类类型对象。但是我看了半天都不明白这段代码到底哪里有问题。后来问了下别人,然后别人告诉我是编译器误把下面这个语句认为是函数声明了,于是b就被当作一个函数而不是一个类类型对象。语句前面的"B"被认为是函数返回值类型,后面的"b"被认为是函数名。不过问题是,为什么"A(n)"会被认为是函数参数呢?"A(n)"怎么看都不像是函数参数啊,函数参数怎么可能会有括号?

B b(A(n));  //这句被编译器认为是函数声明语句

  后来我做了个实验,我尝试定义了一个简单的函数,在这个函数的参数名两边加了一对括号,如下。

#include <iostream>
using namespace std;

int foo(int (n))  //注意这里的参数"n"两边加了括号
{
    return n;
}

int main()
{
    int n = 1;
    cout << foo(n) << endl;
}

  结果发现这段代码可以通过编译!这就代表C++中在函数的形参名两边加括号是被允许的。

  那么我们应该如何避免让编译器把之前那句语句误认为是函数声明语句呢?很简单,在"A(n)"两边再加一对括号就OK了。

B b((A(n)));  //多加一对括号

原文地址:https://www.cnblogs.com/ZhouYiJoe/p/12356039.html

时间: 2024-10-13 10:22:38

小发现: C/C++函数形参名可加括号的相关文章

JS 中函数名后面加与不加括号的区别

1 a.onmouseover = fn1; 2 a.onmouseout = fn2; 3 function fn1(){ 4 div.className = "erweima show"; 5 } 6 function fn2(){ 7 div.className = "erweima hide"; 8 } 只要调用函数进行执行,都必须加括号. 函数是一个对象,函数名是指向这个对象的指针. 函数名后面加上括号就表示立即调用执行这个函数里面的代码. 使用不带圆括号

4-微信小程序开发(小程序默认页面函数说明)

https://www.cnblogs.com/yangfengwu/p/11601299.html 首先说一下,怎么让自己的一个项目更改名字成为一个新的项目 然后用软件导入项目即可 注:如果没有改文件里面的那个"projectname": "lesson3",  ,用软件打开的时候,你会发现 这个地方还会显示lesson2,所以一定要按照上面两步修改完再导入工程, 如果没有修改文件里面那个"projectname": "lesson3

全局变量名、局部变量名和形参名冲突时,覆盖情况

以前错误的认为,全局变量名.局部变量名和形参名相同时,全局变量(也就是外部变量)被形参覆盖,形参被局部变量覆盖. 今天发现这样理解并不对.比如 function foo(num){ var num; console.log(num); } foo(1) // 1 //如果错误的理解为局部变量会覆盖形参的话,会认为会输出undefined 那事实是什么呢.实际上变量名冲突分两种,一种是函数外的变量和函数里的局部变量的冲突,一种是函数内部的冲突. 第一种冲突,我把它理解为是作用域链的上游(最上游是全

关于函数形参的一些讨论

形参的初始化与变量的初始化一样:如果形参具有非引用类型,则复制实参的值,如果形参为引用类型,则它只是实参的别名. 非引用形参: 普通的非引用类型的参数通过复制对应的实参实现初始化.当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值. while 循环体虽然修改了 v1 与 v2 的值,但这些变化仅限于局部参数,而对调用 gcd 函数使用的实参没有任何影响.于是,如果有函数调用gcd(i, j),i 与 j 的值不受 gcd 内执行的赋值操作的影响. #includ

如何写出小而清晰的函数?(JS 版)

本文以 JavaScript 为例,介绍了该如何优化函数,使函数清晰易读,且更加高效稳定. 软件的复杂度一直在持续增长.代码质量对于保证应用的可靠性.易扩展性非常重要. 然而,几乎每一个开发者,包括我自己,在职业生涯中都见过低质量的代码.这东西就是个坑.低质量代码具备以下极具杀伤力的特点: 函数超级长,而且塞满了各种乱七八糟的功能. 函数通常有一些副作用,不仅难以理解,甚至根本没法调试. 含糊的函数.变量命名. 脆弱的代码:一个小的变更,就有可能出乎意料的破坏其他应用组件. 代码覆盖率缺失. 它

关于vue ,v-on 绑定事件时,函数名加括号和不加括号的区别

作者:DDFE链接:https://www.zhihu.com/question/55753541/answer/146504270来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 从官方的文档 事件处理器 - Vue.js 中可以看出通过 `v-on` 中既可以执行一段代码.一个方法.内联 JavaScript 语句,根据不同的情况 Vue 会做不同的处理,具体可以从源码中可以看出(2.1.10版本),在编译阶段,会根据抽象HTML语法树生成代码,从 https:

SQL Server还原和一些小发现

当数据库已经建好在DB里,SQL Server 2005 和 SQL Server 2008使用.Bak文件还原的时候,会出现 error : "The backup set holds a backup of a database other than the existing" 查了网上的方法: 方法一[未验证] [sql] view plaincopy --返回由备份集内包含的数据库和日志文件列表组成的结果集. --主要获得逻辑文件名 --返回由备份集内包含的数据库和日志文件列表

关于PHP魔术方法__call的一点小发现

好久没有上博客园写文章了,今晚终于有点空了,就来写一下昨天的一点小发现. 我自己所知,C++,Java的面向对象都有多态的特点,而PHP没有,但PHP可以通过继承链方法的重写来实现多态的属性.而魔术方法会在特定情况下被触发,我们也可以对其进行重写. ---------------------------------------------------------------------------------------------------------摘抄开始----------------

【JS小技巧】JavaScript 函数用作对象的隐藏问题

用户反馈 @消失的键盘 在论坛反馈了一个问题,在 AppBoxMvc 中的 Title 模型中,如果将 Name 属性改名为小写的 name 属性,就会报错: 因为这是一个 ASP.NET MVC 的项目,而这个属性是通过 TextBoxFor 渲染到页面上的,因此 name 会生成为 DOM 节点的 id 属性: F.SimpleForm() .ID("SimpleForm1") .ShowBorder(false) .ShowHeader(false) .BodyPadding(1