Почему этот явный оператор преобразования работает с g ++, но не с Visual Studio 2013?

В следующем примере содержатся два шаблонных класса для представления градусов и радиан с явным оператором преобразования для приведения между ними. Компилируется и работает с g ++ (ссылка на идеон) но не с Visual Studio 2013 с Visual C++ Compiler Nov 2013 CTP (CTP_Nov2013) как набор инструментов платформы.

#include <iostream>

static const double PI = 3.14159265358979323846;

// Forward declarations
template< typename T > class radians;
template< typename T > class degrees;

template< typename T >
class degrees
{
public:
degrees(const T value)
: value_(value)
{}

template< typename U >
explicit operator U() const
{
return value_ * PI / 180.0;
}

T value() const { return value_; }

private:
T value_;
};

template< typename T >
class radians
{
public:
radians(const T value)
: value_(value)
{}

template< typename U >
explicit operator U() const
{
return (value_* 180.0) / PI;
}

T value() const { return value_; }

private:
T value_;
};

template< typename T >
std::ostream& operator<<(std::ostream& out, const radians<T>& r)
{
return out << r.value() << "r";
}

template< typename T >
std::ostream& operator<<(std::ostream& out, const degrees<T>& r)
{
return out << r.value() << "d";
}int main()
{
using degs = degrees<float>;
using rads = radians<float>;

auto d = degs{10};
auto r = static_cast<rads>(d);

std::cout << d << std::endl;
std::cout << r << std::endl;

return 0;
}

Вывод ошибки Visual Studio:

error C2440: 'static_cast' : cannot convert from 'degrees<float>' to 'rads' degrad.cpp  69  1   degrad
error C3536: 'r': cannot be used before it is initialized   degrad.cpp  72  1   degrad

В чем дело? Почему он работает с g ++, но не с Visual Studio 2013? Какой компилятор делает правильные вещи?

4

Решение

Компилятор, не принимающий указанный фрагмент кода, неисправен, предоставленный код является допустимым и не должен приводить к фатальной диагностике во время компиляции. Другими словами; MSVC делает это неправильно.


СООТВЕТСТВУЮЩИЕ РАЗДЕЛЫ СТАНДАРТА

12.3.2 Функции преобразования [class.conv.fct]

2 Функция может быть explicit (7.1.2), и в этом случае он рассматривается только как пользовательское преобразование для прямая инициализация (8.5). В противном случае пользовательские преобразования не ограничиваются использованием в присваиваниях и инициализациях.

8,5 Инициализаторы [dcl.init]

16 Инициализация, которая происходит в формах

Т х (а);
Т х {а};

а также в new выражения (5.3.4), static_cast Выражения (5.2.9), функциональные преобразования типа записи (5.2.3) и инициализаторы базы и члена (12.6.2) называются прямая инициализация.


КАК БЫ Я РАБОТАЛ Вокруг MSVC++ Быть ошибочным?

  • использование typedef radians<float> rads; вместо using, и либо;

    • Удалить explicit от твоего функция преобразования, или же;

    • инициализируйте вашу переменную используя auto r = rads { d } или же auto r = rads (d);,

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]