为什么只允许一个隐式转换将参数解析为C ++中的函数?

时间:2010-06-25 20:47:37

标签: c++ constructor language-features language-design

这有效:

#include<cstdio>

class A{
public:
    A(int a):var(a){}
    int var;
};

int f(A obj) {
    return obj.var;
}

int main() {
    std::cout<<f(23);  // output: 23
    return 0;
}

虽然没有:

#include<cstdio>

class A{
public:
    A(int a, int b):var1(a), var2(b){}
    int var1, var2;
};

int f(A obj) {
    return (obj.var1 + obj.var2);
}

int main() {

    cout<<f(22, 23); // error: conversion from 'int' to 
                     // non-scalar type 'A' requested
    return 0;
}

第二段代码不起作用,但我找不到足够好的理由。对我来说,代码看起来太奇怪了。

但是在这种情况下只允许一次隐式转换的实际原因是什么?这是一个像这样唯一的语言功能吗?

3 个答案:

答案 0 :(得分:8)

直接的答案是C ++语法在任何情况下都不会将函数参数组合成聚合。在任何情况下,对f(a, b)的调用都不会被视为对f(c)的调用,其中c是由ab的某种组合构成的值。这不是语言的运作方式。对于重载,隐式转换和所有其他目的,始终分别处理每个参数。

至于理由,如果你要求的是什么被允许,你会怎么期望这种情况得到解决:

class A {
  public:
    A(int a) : v1(a) {}
  private:
    int v1;
};

class B {
  public:
    B(int a, int b) : v1(a), v2(b) {}
  private:
    int v1;
    int v2;
};

class C {
  public:
    C(int a, int b, int c) : v1(a), v2(b), v3(c) {}
  private:
    int v1;
    int v2;
    int v3;
};

void f(A obj1, A obj2) { /* ... */ }

void f(B obj) { /* ... */ }

void g(A obj1, B obj2) { /* ... */ }

void g(B obj1, int i) { /* ... */ }

void g(C obj) { /* ... */ }

int main() {
   f(22, 23); // Call f(A,A) or f(B)? 
   g(22, 23, 24); // Call g(A,B) or g(B, int), or g(C)? 
   return 0;
}

答案 1 :(得分:1)

你正在看第二个例子,好像(22,23),其中一个元组(即一对变量是一对),当它们不是时。函数f只接受一个变量。当你试图传递两个失败的变量时。

第一个工作的原因是编译器可以从int转换为A.但是你不能将两个变量转换为单个变量,C ++不允许这样做。

答案 2 :(得分:1)

只有可以使用一个参数调用的构造函数定义隐式转换,因此在第二个示例中没有可能的隐式转换,因为A的构造函数没有一个参数。