![]() |
果断的面包 · Help with lightgbm on ...· 1 周前 · |
![]() |
发怒的小蝌蚪 · 國家華語測驗推動工作委員會· 1 周前 · |
![]() |
慷慨的柑橘 · 测试类 指定启动参数 springboot ...· 1 周前 · |
![]() |
阳光的海豚 · Spring Boot Test | 範宗雲· 1 周前 · |
![]() |
俊逸的萝卜 · Stream Load - Apache ...· 3 天前 · |
![]() |
坏坏的菠萝 · SpringBoot2.x整合Redis数据 ...· 1 月前 · |
![]() |
有爱心的香槟 · MFC中动态控件的创建与响应 - ...· 7 月前 · |
![]() |
瘦瘦的手链 · VSCode proxy设置,解决We ...· 11 月前 · |
![]() |
高大的电影票 · python读取dat数据_dat文件读写_ ...· 1 年前 · |
![]() |
含蓄的瀑布 · Linux发送udp/tcp包最简单方法-n ...· 1 年前 · |
(int*) p显示不符合标记符的规则嘛。
(int*) p 会被编译器认为是一个数据,变量名是绝不可能是这个样子的,所以就用这个数据作为参数构造test对象了,所以强制转换之后不会出错。
为什么 “变量名是绝不可能是这个样子的”?
为什么 “变量名是绝不可能是这个样子的”?
LS我好像在JSP区见过你啊,两个星星,嘿嘿,
你怎么也搞C++啊,我现在正矛盾是搞C++还是JSP呢,能否谈谈见解?
___________________________________
我在学Java之前就会C++了。学Java是因为找到的那份工作要用Java。
现在你两个都可以学,找到工作了之后用啥你就主攻啥。
6.8 Ambiguity resolution [stmt.ambig]
1 There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with
a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration
where the first declarator starts with a (. In those cases the statement is a declaration. [ Note: To disambiguate, the whole
statement might have to be examined to determine if it is an expression-statement or a declaration. This disambiguates
many examples. [ Example: assuming T is a simple-type-specifier (7.1.5),
T(a)->m = 7; / / expression-statement
T(a )++; / / expression-statement
T(a ,5)<<c; / / expression-statement
T(*d)( int ); / / declaration
T(e )[5]; / / declaration
T(f ) = { 1 , 2 }; / / declaration
T(*g)( double (3)); / / declaration
In the last example above, g, which is a pointer to T, is initialized to double(3). This is of course ill-formed for
semantic reasons, but that does not affect the syntactic analysis. —end example ]
一言以蔽之,能作为声明的语句就被认作是声明, 所以这里test(p)背认定为声明而不是构造一个临时的test变量。
“test(p)语句试图把生成的test实例转换为int*类型,”这里不存在“实例类型转换“的问题,int*类型的实例是可以转换为test实例的,可能vc6.0在声明和定义之间做出错误或是过晚的抉择造成的。
补充解释一下这两个错:
error C2040: “p”: “test”与“int *”的间接寻址级别不同
error C2512: “test”: 没有合适的默认构造函数可用
单纯的语句 test(p); 将定义一个test类实例p,相当于 test p; 但test并没有定义默认构造函数,所以有了第二个错。另因为p以声明为int*类型,而test(p)语句试图把生成的test实例转换为int*类型,这就引发了第一个错,因为一个test实例和一个指针有着不同的寻址级(different levels of indirection)。
test((int* p))将会通过编译,是因为这里(int* p)被解析为构造函数的参数,而非新test实例的名称。这句语句在运行时将生成一个无名test实例,其pi被初始化为p;因为无名,该实例不可访问,所以纯粹无用。
这里g++和vs2005两个编译器报不同的错误是似乎是因为两者解析的顺序的不同。在vs2005里修正了第一个错误后,以如下语句编译,将会得到和g++同样的报错。
int p=9;
test(p);//error C2371: 'p' : redefinition; different basic types
p 本来就是 int*
为什么(int *)p 后就可以,不是多余了吗?强制类型转换是不是还有其他什么用途?
你怎么也搞C++啊,我现在正矛盾是搞C++还是JSP呢,能否谈谈见解?
test(x)和test x是等价的,都是申明变量。
原来()可以用在申明中把变量名包起来,通常申明函数指针的时候会用到,原来用于一般变量也可以这样。
(int*) p 会被编译器认为是一个数据,变量名是绝不可能是这个样子的,所以就用这个数据作为参数构造test对象了,所以强制转换之后不会出错。
C++太神奇了,呵呵!
我试了一下,如果再定义一个void test(int* p)的函数,编译就不会报错了。
在没有void test(int*)函数的时候,test((int*) p)会调用构造函数,在构造里加一条输出语句就知道了。
但是定义了void test(int*)之后,test(p)和test((int*) p)都会去调用函数——这到是说得过去
唯一不明白的是,为什么没有(int*)的时候编译不过,有了就没问题了。
p 本来就是 int*
为什么(int *)p 后就可以,不是多余了吗?强制类型转换是不是还有其他什么用途?
test.cpp:19: error: conflicting declaration 'test p'
test.cpp:18: error: 'p' has a previous declaration as `int*p'
test.cpp:19: error: declaration of `test p'
test.cpp:18: error: conflicts with previous declaration `int*p'
test.cpp:19: error: no matching function for call to `test::test()'
test.cpp:5: note: candidates are: test::test(const test&)
test.cpp:8: note: test::test(int*)
上面代码用g++编译报上面的错误,g++编译器认为test(p);等价于 test p;当着变量定义了,和前面的定义冲突了。
如果你改成 test a(p)就不会有问题了。