試しにGCCでも試してみて、GCCのほうではちゃんとした動作をしましたがなぜ同じ動作にならないのかわかりませんでした。
GCCのほうは使い初めて間もないのでテストのみです。
意図しない挙動になったのはVec3です。Vec2はVCでもGCCでもちゃんとした動作になりました。
ご教授よろしくお願いします。
環境:
Visual Studio 2013, Win7
(GCC5.2.0)
/* Math.h */
/* 使用しているところのみ抜粋 */
#pragma once
#include <cmath>
template <typename T>
class Math
{
public:
static const T Zero; /* 0.0 */
static const T One; /* 1.0 */
};
template <> const int Math<int>::Zero = 0;
template <> const float Math<float>::Zero = 0.0f;
template <> const double Math<double>::Zero = 0.0;
template <> const long double Math<long double>::Zero = 0.0L;
template <> const int Math<int>::One = 1;
template <> const float Math<float>::One = 1.0f;
template <> const double Math<double>::One = 1.0;
template <> const long double Math<long double>::One = 1.0L;
typedef Math<int> Mathi;
typedef Math<float> Mathf;
typedef Math<double> Mathd;
typedef Math<long double> Mathdl;
/* Vec2.h */
#pragma once
namespace std
{
template <typename, typename>
class basic_ostream;
}
#include "Math.h"
template <typename T>
struct Vec2
{
union
{
struct
{
T X;
T Y;
};
T Data[2];
};
static const Vec2 Zero;
static const Vec2 One;
static const Vec2 UnitX;
static const Vec2 UnitY;
Vec2() :
X(Math<T>::Zero), Y(Math<T>::Zero)
{
}
Vec2(T x, T y) :
X(x), Y(y)
{
}
};
template <typename T>
const Vec2<T> Vec2<T>::Zero(Math<T>::Zero, Math<T>::Zero);
template <typename T>
const Vec2<T> Vec2<T>::One(Math<T>::One, Math<T>::One);
template <typename T>
const Vec2<T> Vec2<T>::UnitX(Math<T>::One, Math<T>::Zero);
template <typename T>
const Vec2<T> Vec2<T>::UnitY(Math<T>::Zero, Math<T>::One);
template <typename CharT, typename Traits, typename T>
inline std::basic_ostream<CharT, Traits>& operator << (std::basic_ostream<CharT, Traits>& os, const Vec2<T>& v)
{
os << v.X << ' ' << v.Y;
return os;
}
/* Vec3.h */
#pragma once
#include "Vec2.h"
template <typename T>
struct Vec3
{
union
{
struct
{
T X;
T Y;
T Z;
};
struct
{
Vec2<T> XY; //これがあるかないかでVCの挙動がおかしくなる
};
T Data[3];
};
static const Vec3 Zero;
static const Vec3 One;
static const Vec3 UnitX;
static const Vec3 UnitY;
static const Vec3 UnitZ;
Vec3() :
Vec3(Math<T>::Zero, Math<T>::Zero, Math<T>::Zero)
{
}
Vec3(T x, T y, T z) :
//XY(x, y), Z(z) //VCの場合はこちらを使用するとうまく動作、GCCではエラー
X(x), Y(y), Z(z)
{
}
Vec3(const Vec2<T>& v, T z) :
Vec3(v.X, v.Y, z)
{
}
};
template <typename T>
const Vec3<T> Vec3<T>::Zero(Math<T>::Zero, Math<T>::Zero, Math<T>::Zero);
template <typename T>
const Vec3<T> Vec3<T>::One(Math<T>::One, Math<T>::One, Math<T>::One);
template <typename T>
const Vec3<T> Vec3<T>::UnitX(Math<T>::One, Math<T>::Zero, Math<T>::Zero);
template <typename T>
const Vec3<T> Vec3<T>::UnitY(Math<T>::Zero, Math<T>::One, Math<T>::Zero);
template <typename T>
const Vec3<T> Vec3<T>::UnitZ(Math<T>::Zero, Math<T>::Zero, Math<T>::One);
template <typename CharT, typename Traits, typename T>
inline std::basic_ostream<CharT, Traits>& operator << (std::basic_ostream<CharT, Traits>& os, const Vec3<T>& v)
{
os << v.X << ' ' << v.Y << ' ' << v.Z;
return os;
}
/* main.cpp */
#ifndef _MSC_VER
#pragma anon_unions
#else
#pragma warning(disable: 4201)
#endif
#include "Vec2.h"
#include "Vec3.h"
#include "Vec4.h"
#include <iostream>
using std::cout;
using std::endl;
typedef Vec2<float> Vec2f;
typedef Vec3<float> Vec3f;
typedef Vec4<float> Vec4f;
int main(int argc, char** argv)
{
cout << std::fixed;
const auto v2 = sizeof(Vec2f);
const auto v3 = sizeof(Vec3f);
const auto v4 = sizeof(Vec4f);
cout << Vec2f::UnitX << endl;
cout << Vec3f::UnitX << endl;
cout << Vec3f::UnitY << endl;
cout << Vec3f::UnitZ << endl;
cout << Vec3f::UnitX.XY << endl;
return 0;
}