Reputation: 13
Right now I'm working on a project where convertibility between two classes (A and B) is highly desirable. I've created a function myFunc() that takes an object of class A as its argument, and I've passed it an object of class B.
The reason I expected this to work is that B can be implicitly converted to an integer, and A can be implicitly constructed with an integer. I expected these two processes to occur so that an object of class B would implicitly be converted to an object of class A. This was not the case.
When I try to pass in an object of class B to myFunc(), I get the error: error: could not convert 'b' from 'B' to 'A'
.
Interestingly, however, I can pass in an object of class B that I explicitly cast to an integer, or an explicitly constructed object of class A which takes an object of class B as its argument. It seems that only one implicit process (whether it be a converting constructor or an implicit conversion) can happen in a single line. Why is this the case? Is there any way to get around this issue?
I know that a simple solution would be to create a constructor in A that takes an object of class B as its argument, or to create an operator in B that converts an object of class B to an object of class A. For my purposes, however, these solutions should not be used unless absolutely necessary.
I'm still learning C++ (I've come over from Java). Hopefully the code below will clarify what I'm talking about. Thank you for your feedback in advance.
#include <iostream>
// objects of class A can be (implicitly) constructed with an int
struct A {
A(int) {}
};
// objects of class B can be (implicitly) converted to an int
struct B {
B(int) {}
operator int() { return 0; }
};
// myFunc takes an object of class A
void myFunc(A)
{ }
// why can't myFunc convert the argument b like the following: B -> int -> A?
int main()
{
B b(5);
// These work:
myFunc((int) b);
myFunc(A(b));
// This does not:
myFunc(b);
}
Note: The code above should compile properly until myFunc(b);
is commented out.
Upvotes: 1
Views: 83
Reputation: 179779
What you're looking for is called a conversion sequence in C++. To get from one type to another, there can be only a limited number of steps. Importantly, there can be at most one step from each of the possible categories. E.g. you can have at most one numeric promotion ( e.g. short
to long
.). Importantly for your example, there can be at most one user-defined conversion. This is either a converting constructor (Foo::Foo(Bar)
) or a conversion function (Bar::operator Foo
). Your example needs both.
Upvotes: 1