Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
// Template Instantiation Test with "Visual C++ 2013" (C++11) // 18/10/2014 by Lukas Hermanns #include <iostream> #include <cstdlib> /* --- Global constants --- */ static const float pi = 3.14159265359f; static const double pi64 = 3.1415926535897932384626433832795028841971693993751; /* --- Angle base class --- */ /** Angle base class. This class stores a value in common angle units which can be converted into radians or degrees. The internal angle units are in the range [0.0 .. 1.0), i.e. 1.0 is a 360 degrees, or rather a 2*pi radians rotation. \tparam T Specifies the data type. This should be float or double. \tparam Definition Specifies the definition of a full rotation. This must be a struct that implements the following interface: \code struct ExampleDefinition { // Full rotation. This can be 1.0 (for abstract abgles), 360.0 (for degrees) or 2*PI<T>() (for radians). static T FullRotation(); }; \endcode */ template <typename T, class Definition> class AngleBase { public: typedef AngleBase<T, Definition> ThisType; AngleBase() = default; //! Constructor for implicit conversion between angle definitions. template <typename OtherDefinition> AngleBase(const AngleBase<T, OtherDefinition>& other) : angle_{ other.NormalizedAngle() * ThisType::FullRotation() } { } explicit AngleBase(const T& angleUnits) : angle_{ angleUnits } { } inline ThisType& operator += (const ThisType& other) { angle_ += other.angle_; return *this; } inline ThisType& operator -= (const ThisType& other) { angle_ -= other.angle_; return *this; } inline ThisType& operator *= (const T& factor) { angle_ *= factor; return *this; } inline ThisType& operator /= (const T& factor) { angle_ /= factor; return *this; } /** Converts this angle to an angle of the other angle type. \tparam OtherType This must be an "AngleBase" class, e.g. Angle, Degree or Radian. \return The converted angle. \note There is a BUG inside the MSVC12 compiler which instantiates this function wrong! This happens when this function is called consecutively with different template arguments. This totally works for GCC 4.7+ but unfortunately not correctly for MSVC12. */ template <template <typename> class OtherType> inline T Get() const { return NormalizedAngle() * OtherType<T>::FullRotation(); } //! Returns the internal angle. This value depends on the angle definition. inline T GetAngle() const { return angle_; } //! Returns the normalized angle, i.e. in the range [0.0 .. 1.0). inline T NormalizedAngle() const { return angle_ / ThisType::FullRotation(); } /** Returns the full rotation of this angle definition. This can be 1.0 (for unit angles), 360 (for degrees) or 2*pi (for radians). */ static inline T FullRotation() { return Definition::FullRotation(); } private: T angle_ { 0 }; }; /* --- Global "AngleBase" operators --- */ template <typename T, class DefinitionLHS, class DefinitionRHS> AngleBase<T, DefinitionLHS> operator + (const AngleBase<T, DefinitionLHS>& lhs, const AngleBase<T, DefinitionRHS>& rhs) { auto result = lhs; result += AngleBase<T, DefinitionLHS>(rhs); return result; } template <typename T, class DefinitionLHS, class DefinitionRHS> AngleBase<T, DefinitionLHS> operator - (const AngleBase<T, DefinitionLHS>& lhs, const AngleBase<T, DefinitionRHS>& rhs) { auto result = lhs; result -= AngleBase<T, DefinitionLHS>(rhs); return result; } template <typename T, class Definition> AngleBase<T, Definition> operator * (const AngleBase<T, Definition>& lhs, const T& rhs) { auto result = lhs; result *= rhs; return result; } template <typename T, class Definition> AngleBase<T, Definition> operator * (const T& lhs, const AngleBase<T, Definition>& rhs) { auto result = rhs; result *= lhs; return result; } template <typename T, class Definition> AngleBase<T, Definition> operator / (const AngleBase<T, Definition>& lhs, const T& rhs) { auto result = lhs; result /= rhs; return result; } template <typename T, class Definition> AngleBase<T, Definition> operator / (const T& lhs, const AngleBase<T, Definition>& rhs) { auto result = rhs; result /= lhs; return result; } /* --- Angle --- */ //! Angle rotation definition. template <typename T> struct AngleDefinition { static inline T FullRotation() { return T(1); } }; //! AngleBase specialization for unit angles in the range [0.0 .. 1.0). template <typename T = float> using Angle = AngleBase<T, AngleDefinition<T>>; /* --- Degree --- */ //! Degree rotation definition. template <typename T> struct DegreeDefinition { static inline T FullRotation() { return T(360); } }; //! AngleBase specialization for degrees in the range [0.0 .. 360). template <typename T = float> using Degree = AngleBase<T, DegreeDefinition<T>>; /* --- Radian --- */ //! Radian rotation definition. template <typename T> struct RadianDefinition { static inline T FullRotation() { return T(pi64*2.0); } }; //! AngleBase specialization for radians in the range [0.0 .. 2*pi). template <typename T = float> using Radian = AngleBase<T, RadianDefinition<T>>; /* --- Main function --- */ int main() { // Abstract angle in the range [0.0 .. 1.0), // constructed by (90 degrees) + (pi/2 radians) = 0.5 (half rotation). Angle<float> angle = Degree<float>(90.0f) + Radian<float>(pi/2); #if 1 auto degree = angle.Get<Degree>(); auto radian = angle.Get<Radian>(); // MSVC COMPILER FAILURE -> angle.Get<Degree> will be instantiated but angle.Get<Radian> is required !!! std::cout << "Angle = " << angle.GetAngle() << std::endl; std::cout << "Degree = " << degree << std::endl; std::cout << "Radian = " << radian << std::endl; #else auto radian = angle.Get<Radian>(); auto degree = angle.Get<Degree>(); // MSVC COMPILER FAILURE -> angle.Get<Radian> will be instantiated but angle.Get<Degree> is required !!! std::cout << "Angle = " << angle.GetAngle() << std::endl; std::cout << "Degree = " << degree << std::endl; std::cout << "Radian = " << radian << std::endl; #endif system("pause"); return 0; } |
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »LukasBanana« (18.10.2014, 14:56)
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Zitat von »Spiele Programmierer«
Also bei mir geht es in allen Konfigurationen in einem neu erstellten Projekt in VS2013 problemlos.
Zitat von »Spiele Programmierer«
Im Speichern von 0 ... 1 sehe ich auch keinen Sinn, gibt es überhaupt irgendeinen Kontext in dem das Sinnvoll wäre?
C-/C++-Quelltext |
|
1 2 |
auto degree = Degree<float>(); auto radian = degree.Get<Radian>(); |
C-/C++-Quelltext |
|
1 2 |
auto degree = Degree<float>(); auto radian = degree.Get<Radian<float>>(); |
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (18.10.2014, 16:38)
Werbeanzeige