这有效:
#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;
}
第二段代码不起作用,但我找不到足够好的理由。对我来说,代码看起来太奇怪了。
但是在这种情况下只允许一次隐式转换的实际原因是什么?这是一个像这样唯一的语言功能吗?
答案 0 :(得分:8)
直接的答案是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;
}
答案 1 :(得分:1)
你正在看第二个例子,好像(22,23),其中一个元组(即一对变量是一对),当它们不是时。函数f只接受一个变量。当你试图传递两个失败的变量时。
第一个工作的原因是编译器可以从int转换为A.但是你不能将两个变量转换为单个变量,C ++不允许这样做。
答案 2 :(得分:1)
只有可以使用一个参数调用的构造函数定义隐式转换,因此在第二个示例中没有可能的隐式转换,因为A
的构造函数没有一个参数。