According to the working draft N3337 (the most similar draft to the published ISOC++11 standard) the answer is at most one.
N3337:
At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.
[ Example: struct X { operator int(); }; struct Y { operator X(); }; Y a; int b = a; // error // a.operator X().operator int() not tried int c = X(a); // OK: a.operator X().operator int() —end example ]
But according to the result of compiling main.cpp with gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 and running a.out with the quoted statements in Ubuntu 14.04.3 LTS, the answer is not at most one.
main.cpp:
#include <iostream>
struct As
{
operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
};
struct Bs
{
operator int(){ std::cout<<"operator Bs::int()"<<std::endl; return As(); }
};
int main()
{
int i=Bs();
return 0;
}
compiling and running from terminal:
$ g++ -std=c++11 main.cpp
$ ./a.out
the result (output):
operator Bs::int()
operator As::int()
Did I misunderstand something or is N3337 wrong or does gcc contains a bug?
There are no double conversions getting executed here.
You have two individual conversions taking place, in two separate places.
One conversion is in
B::operator int()
.The second conversion is in your
main()
.Let's try to think through this logically:
Remove main() entirely from your translation unit. Do you see any double conversions?
No.
Now, let's create a header file containing the following bits, call it
structures.H
:Now, create a
structures.C
file, containing the contents of each one of these operators:Ok, do you still see any double-conversions here? No.
Now, create your main.C:
Do you see any double conversions taking place here? No, even though what we have now, with the two translation units, the same exact code you started with.