Why is only one implicit conversion allowed to resolve the parameters to a function in C++?
This works:
#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;
}
while this doesn't:
#include<cstdio>
class A{
public:
A(int a,开发者_如何学Go 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;
}
The second piece of code does not work, but I am not able to find a good-enough reason why it doesn't. To me, the code just looks too odd to work.
But what is the actual reason that there is only one implicit conversion allowed in situations like this? Is it a this-is-like-this-only language feature?
The direct answer is that the C++ grammar does not combine function arguments into aggregates under any circumstances. In no case will a call to f(a, b)
be treated as a call to f(c)
where c
is a value constructed from some combination of a
and b
. That's just not how the language works. Each argument is always treated separately for overloading, implicit conversion, and all other purposes.
As for a rationale, if what you're asking about were allowed, how would you expect this situation to be resolved:
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;
}
You are looking at the second example as if (22, 23) where a tuple (that is, a single variable that is a pair) when they are not. The function f only takes one variable. When you try to pass it two variables that will fail.
The reason the first one works is that the compiler can cast from an int to a A. However you can't cast two variables to a single variable, C++ doesn't allow that.
Only constructors that can be called with one argument define implicit conversions, so there are no implicit conversions possible in your second example since no constructor of A
takes one argument.
精彩评论