问题
I am aware of the fact that C++ allows only a single user-defined implicit conversion when converting between types. However, I recently came across a situation where it seems like double user-defined implicit conversions are allowed on initialization.
Consider the following classes:
//fractions
class Rational {
public:
int num, den;
// default constructor, etc.
Rational(int n) : num(n), den(1) {} // NOT explicit
// arithmetic and compound assignment defined between two Rational's.
};
//numbers of the form a + b sqrt(N), where a, b are of type R
template<typename R, int N>
class RingExtension {
public:
R a, b;
// default constructor, etc.
RingExtension<R, N>(R a) : a(a), b(0) {} // NOT explicit
// arithmetic and compound assignment defined between two RingExtension<R, N>'s.
};
As expected, the following will not compile:
int main() {
RingExtension<Rational, 2> x;
x /= 3; // ERROR! Can't do the conversion int -> Rational -> RingExtension<Rational, 2>
x /= (Rational)3; // this does work
}
However, the following does compiles in Visual Studio 2013:
int main() {
RingExtension<Rational, 2> x = 3; // int -> Rational -> RingExtension<Rational, 2>
}
Why is the double user-defined conversion allowed in the latter situation? Is Visual Studio not standard-compliant in this particular situation? Or is there some exception in the standard for initialization?
EDIT: As Kerrek SB suggested, I have tested my code in clang and gcc through Wandbox. Both compilers spat out an error on the initialization, as one would expect. Question remains, who is in the wrong here? It would seem that Visual Studio is too permissive, but it would be great if someone could confirm this.
EDIT: The full source code for these classes, including the main()-function, can be found here: http://pastebin.com/JNSvkwi0#
来源:https://stackoverflow.com/questions/32700574/multiple-user-defined-conversions-on-initialization