Этот кусок кода, конечно, глуп, но я написал его только для иллюстрации проблемы.
Вот оно:
#include <iostream>
using namespace std;
struct foo {
int a = 42;
template <typename T>
operator T* () {
cout << "operator T*()\n";
return reinterpret_cast<T*>(&a);
}
template <typename T>
operator const T* () const {
cout << "operator const T*() const\n";
return reinterpret_cast<const T*>(&a);
}
template <typename T>
T get() {
cout << "T get()\n";
return this->operator T();
}
};
int main() {
foo myFoo;
cout << *myFoo.get<const int*>() << '\n';
}
Вывод при компиляции с Visual Studio 2019 (ISO C ++ 17, /Ox
):
T get()
operator const T*() const
42
Выход с gcc 8.3 (-std=c++17
, -O3
):
T get()
operator T*()
42
Так что мне интересно, почему два компилятора решили вызывать разные константно-квалифицированные преобразования для данного кода?
Если я изменю get()
на get() const
, тогда оба вызовут const
версию преобразования. Но не нарушает ли VS стандарт, вызывая преобразование const
из метода, который не помечен const
?
EDIT:
Чтобы устранить некоторую путаницу вокруг reinterpret_cast
, , вот версия без нее , которая по-прежнему выдает одинаковый вывод на обоих компиляторах.