2017-04-25 32 views
2
#include <iostream> 
using namespace std; 

struct A { 
    A(int i) { 
     cout << "1 args" << endl; 
    } 
    A(int i, int j) { 
     cout << "2 args" << endl; 
    } 
}; 

void foo(int i) { 
    cout << "1 args" << endl; 
} 
void foo(int i, int j) { 
    cout << "2 args" << endl; 
} 

int main() { 
    int i, j; 
    A(i, j); 
    (A)(i, j); 
    foo(i, j); 
    (foo)(i, j); 
} 

输出:构造的在C A二义性++

2 args 
1 args 
2 args 
2 args 

我知道结果 “1个ARGS” 是因为 “(I,J)” 作为 “J” 进行评价。

但考虑构造函数的区别的原因也是函数?

+0

构造函数不是你解释意义上的函数。 '(A)(i,j)'是一个类型转换,而不是'''构造函数的显式调用。你可以达到与'static_cast (i,j)'相同的效果。 – Peter

回答

5

构造函数是成员函数;如果您想尝试像调用其他任何函数一样“调用构造函数”,则代码可能是a.A(i,j);,而您在已创建的某个对象a上使用成员访问运算符。但这是不允许的,因为构造函数只是作为对象创建的一部分被调用。

  1. A(i, j);匹配的语法postfix-expression:simple-type-specifier(expression-list)。该语法的含义是创建该类型的prvalue表达式,其中expression-list是构造函数参数。

  2. (A)(i, j);与该语法不匹配,因为simple-type-specifier不能加括号。但它确实匹配cast-expression,所以它是表达式(i, j)(这是一个逗号运算符表达式)转换为A。在这种情况下,转换为类类型的结果涉及构造该类类型的临时。

  3. foo(i, j);匹配postfix-expression:postfix-expression(expression-list),这是呼叫与参数列表的功能foo

  4. (foo)(i, j);也符合同样的规则,因为(postfix-expression)仍然是一个postfix-expression

+0

我曾经使用过Bison来编写解析器。你的回答对我来说已经够清楚了。 – chaosink

0

对于那些寻找一个少技术答案,我会读M.M answer,如:

一个foo是不是,所以:

(A)(i, j); // cast to A the result of (i, j) ==> calls A(j) in conversion 
(foo)(i, j) // still the same as foo(i, j)