c++ - Why does this explicit conversion operator work with g++ but not Visual Studio 2013? -
the following example contains 2 templated classes represent degrees , radians explicit conversion operator cast between them. compiles , runs g++ (ideone link) not visual studio 2013 visual c++ compiler nov 2013 ctp (ctp_nov2013)
platform toolset.
#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; }
the visual studio error output:
error c2440: 'static_cast' : cannot convert 'degrees<float>' 'rads' degrad.cpp 69 1 degrad error c3536: 'r': cannot used before initialized degrad.cpp 72 1 degrad
what's wrong? why work g++ not visual studio 2013? compiler doing right thing?
a compiler not accepting metioned snippet faulty, code provided legal , should not yield fatal diagnostic during compilation. in other words; msvc doing wrong.
relevant sections of standard
12.3.2 conversion functions
[class.conv.fct]
2 function may
explicit
(7.1.2), in case considered user-defined conversion direct-initialization (8.5). otherwise, user-defined conversions not restricted use in assignments , initializations.
8.5 initializers
[dcl.init]
16 initialization occurs in forms
t x (a);
t x {a};as in
new
expressions (5.3.4),static_cast
expressions (5.2.9), functional notation type conversions (5.2.3), , base , member initializers (12.6.2) called direct-initialization.
how work around msvc++
being faulty?
use
typedef radians<float> rads;
instead ofusing
, , either;remove
explicit
conversion function, or;initialize variable using
auto r = rads { d }
orauto r = rads (d);
.
Comments
Post a Comment