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)
第二段代码不起作用,但我找不到足够好的理由.对我来说,代码看起来太奇怪了.
但是在这种情况下只允许一次隐式转换的实际原因是什么?它是一个像这样唯一的语言功能吗?
直接的答案是C++语法在任何情况下都不会将函数参数组合成聚合.在任何情况下将一个呼叫到f(a, b)被视为一个呼叫f(c),其中c是从的一些组合构成的值a和b.这不是语言的运作方式.对于重载,隐式转换和所有其他目的,始终单独处理每个参数.
至于理由,如果你要求的是什么被允许,你会如何预期这种情况得到解决:
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)