Недавно узнал, что обнаружен новый серьезный бан MS VC++ 2010.
Рассмотрим код
template <typename T1>
class A
{
template <typename T2>
A<T1> & operator =( const A<T2> & )
{
return ( *this );
}
};
int main()
{
A<int> a1;
A<double> a2;
a1 = a2;
return ( 0 );
}
Этот код компилируется MS VC++ 2010 и выполняется,хотя на самом деле компилятор должен выдавать сообщение об ошибке. Почему?
В классе
A определен
закрытый (private) шаблонный оператор присваивания. Он закрытый, потому что для классов с ключевым словом
claa в отличии от классов с ключевым словом
struct члены класса по умолчанию являются закрытыми, если не указан явно спецификатор доступа. Итак, в классе
A имеется
закрытый шаблонный оператор присваивания и созданный компилятором по умолчанию
копирующий оператор присваивания, который является
открытым.
Из этих двух операторов присваивания для выражения
a1 = a2; компилятор должен выбрать шаблонный оператор присваивания, так как типы
a1 и
a2 различны. Но так как этот шаблонный оператор присваивания закрытый, то компилятор соответственно должен выдать сообщение об ошибке. Однако MS VC++ 2010, как я уже указал, компилирует и запускает на выполнение этот код.
Нужно все же отметить,что компилятор помечает в исходном коде знак присваивания в выражении
a1 = a2; красной волнистой линией,и если подвести к этому знаку присваивания курсор,то только тогда появляется сообщение об ошибке.
Я проверил, и оказалось, что этот баг компилятора MS VC++ 2010 возникает тогда, когда используются функции-операторы. Например,
template <typename T1>
class A
{
template <typename T2>
A<T1> & operator =( const A<T2> & )
{
return ( *this );
}
template <typename T2>
A<T1> & operator +=( const A<T2> & )
{
return ( *this );
}
template <typename T2>
const A<T1> operator +( const A<T2> & ) const
{
return ( A<T1>() );
}
};
int main()
{
A<int> a1;
A<double> a2;
a1 = a2;
a1 += a2;
a1 = a1 + a2;
return ( 0 );
}
Этот код,который не должен компилироваться, успешно компилируется и выполняется компилятором MS VC++ 2010.
Но если заменить оператор-функцию обычной функцией, то код уже не компилируется, и MS VC++ 2010 выдает сообщение об ошибке, как то и должно быть.
template <typename T1>
class A
{
template <typename T2>
A<T1> & f( const A<T2> & )
{
return ( *this );
}
};
int main()
{
A<int> a1;
A<double> a2;
a1.f( a2 );
return ( 0 );
}
Это очень серьезный баг MS VC++ 2010, и отловить его очень тяжело, так как можно просто не заметить ошибку.