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

Laz*_*zer 1 c++ language-features constructor 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;
}
Run Code Online (Sandbox Code Playgroud)

虽然这不是:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Tyl*_*nry 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;
}
Run Code Online (Sandbox Code Playgroud)