我知道在类型之间进行转换时,C ++只允许单个用户定义的隐式转换。但是,我最近遇到了一种情况,即在初始化时似乎允许双用户定义的隐式转换 。
考虑以下课程:
//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.
};
正如所料,以下内容无法编译:
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
}
但是,以下 在Visual Studio 2013中进行编译:
int main() {
RingExtension<Rational, 2> x = 3; // int -> Rational -> RingExtension<Rational, 2>
}
为什么在后一种情况下允许双用户定义的转换?在这种特殊情况下,Visual Studio是否不符合标准?或者初始化标准中有一些例外吗?
编辑:正如Kerrek SB建议的那样,我已经通过Wandbox在clang和gcc中测试了我的代码。正如人们所预料的那样,两个编译器都会在初始化时吐出错误。问题仍然存在,谁在这里错了?看起来Visual Studio过于宽松,但如果有人能证实这一点,那将会很棒。编辑:这些类的完整源代码,包括main() - 函数,可以在这里找到:http://pastebin.com/JNSvkwi0#