A
Asfand Yar Qazi
Sorry about this, but its driving me up the wall.
First some code:
typedef unsigned int size_t;
struct AddOp
{
template<class I1, class I2> static inline float
call(size_t i, const I1& i1, const I2& i2)
{
return i1 + i2;
}
};
struct MultOp
{
template<class I1, class I2> static inline float
call(size_t i, const I1& i1, const I2& i2)
{
return i1 * i2;
}
};
class Expr
{
float data;
public:
Expr(float arg_data) : data(arg_data) {}
float
operator[](size_t i) const {return data;}
};
template<class I1, class I2, class Op>
class Expr3
{
const I1& i1;
const I2& i2;
public:
Expr3(const I1& ai1, const I2& ai2)
: i1(ai1), i2(ai2)
{
}
float
operator[](size_t i) const
{
return Op::call(i, i1, i2);
}
template<class E>
Expr3<Expr3, E, AddOp>
operator+(const E& e) const
{
return Expr3<Expr3, E, AddOp>(*this, e);
}
};
struct Vec4
{
Vec4(float all)
: x(all), y(all), z(all), w(all)
{
}
Vec4(float ax, float ay, float az, float aw = 1)
: x(ax), y(ay), z(az), w(aw)
{
}
float x, y, z, w;
float
operator[](size_t i) const
{
switch(i) {
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: return 0xdeadbeef;
}
// HACKHACKHACK
// return (&x)
}
const Vec4&
operator=(float arg)
{
x = y = z = w = arg; return *this;
}
Expr3<Vec4, Expr, MultOp>
operator*(float e) const
{
// ****
return Expr3<Vec4, Expr, MultOp>(*this, Expr(e));
}
template<class E>
const Vec4&
operator=(const E& e)
{
x = e[0]; y = e[1]; z = e[2]; w = e[3]; return *this;
}
};
template<class T>
Expr3<Expr3<Vec4, Expr, MultOp>, Expr3<Vec4, Expr, MultOp>, AddOp>
dostuff(const T& arg)
{
return (arg * 0.9999f) + (arg * 0.00001f);
}
int
main()
{
const float ARG1 = 3.40282347e+38f;
Vec4 v1(ARG1), v2(ARG1);
v2 = dostuff(v1);
}
As you may have guessed its a slightly less than naive attempt at
doing a template expressions 3D vector maths library. (The above code
is just a test case composed of parts of the library.)
Here's the thing though: I get crashes when I run this. A reliable
source tell me that "The life time of Expr(e) is just this statement
so this is invalid." (referring to line underneath the ****)
I think I have to make the following modifications:
struct Vec4
{
...
Expr3<Vec4, Expr, MultOp>
operator*(Expr e) const
{
// ****
return Expr3<Vec4, Expr, MultOp>(*this, e);
}
...
};
// Get rid of dostuff method
....
int
main()
{
const float ARG1 = 3.40282347e+38f;
Vec4 v1(ARG1), v2(ARG1);
v2 = (v1 * Expr(0.9999f)) + (v1 * Expr(0.00001f));
}
I don't understand why this change should fix the program. I don't
understand why other temporaries don't end up crashing the program.
For example the temporary generated with the line "return Expr3<Vec4,
Expr, MultOp>(*this, e)"
Could someone clear this up for me? I'm really lost.
Also, could someone give me any critique as to any fundamental design
flaws of the code above? Or any other errors or undesirable code they
see?
Thanks,
Asfand Yar
First some code:
typedef unsigned int size_t;
struct AddOp
{
template<class I1, class I2> static inline float
call(size_t i, const I1& i1, const I2& i2)
{
return i1 + i2;
}
};
struct MultOp
{
template<class I1, class I2> static inline float
call(size_t i, const I1& i1, const I2& i2)
{
return i1 * i2;
}
};
class Expr
{
float data;
public:
Expr(float arg_data) : data(arg_data) {}
float
operator[](size_t i) const {return data;}
};
template<class I1, class I2, class Op>
class Expr3
{
const I1& i1;
const I2& i2;
public:
Expr3(const I1& ai1, const I2& ai2)
: i1(ai1), i2(ai2)
{
}
float
operator[](size_t i) const
{
return Op::call(i, i1, i2);
}
template<class E>
Expr3<Expr3, E, AddOp>
operator+(const E& e) const
{
return Expr3<Expr3, E, AddOp>(*this, e);
}
};
struct Vec4
{
Vec4(float all)
: x(all), y(all), z(all), w(all)
{
}
Vec4(float ax, float ay, float az, float aw = 1)
: x(ax), y(ay), z(az), w(aw)
{
}
float x, y, z, w;
float
operator[](size_t i) const
{
switch(i) {
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: return 0xdeadbeef;
}
// HACKHACKHACK
// return (&x)
}
const Vec4&
operator=(float arg)
{
x = y = z = w = arg; return *this;
}
Expr3<Vec4, Expr, MultOp>
operator*(float e) const
{
// ****
return Expr3<Vec4, Expr, MultOp>(*this, Expr(e));
}
template<class E>
const Vec4&
operator=(const E& e)
{
x = e[0]; y = e[1]; z = e[2]; w = e[3]; return *this;
}
};
template<class T>
Expr3<Expr3<Vec4, Expr, MultOp>, Expr3<Vec4, Expr, MultOp>, AddOp>
dostuff(const T& arg)
{
return (arg * 0.9999f) + (arg * 0.00001f);
}
int
main()
{
const float ARG1 = 3.40282347e+38f;
Vec4 v1(ARG1), v2(ARG1);
v2 = dostuff(v1);
}
As you may have guessed its a slightly less than naive attempt at
doing a template expressions 3D vector maths library. (The above code
is just a test case composed of parts of the library.)
Here's the thing though: I get crashes when I run this. A reliable
source tell me that "The life time of Expr(e) is just this statement
so this is invalid." (referring to line underneath the ****)
I think I have to make the following modifications:
struct Vec4
{
...
Expr3<Vec4, Expr, MultOp>
operator*(Expr e) const
{
// ****
return Expr3<Vec4, Expr, MultOp>(*this, e);
}
...
};
// Get rid of dostuff method
....
int
main()
{
const float ARG1 = 3.40282347e+38f;
Vec4 v1(ARG1), v2(ARG1);
v2 = (v1 * Expr(0.9999f)) + (v1 * Expr(0.00001f));
}
I don't understand why this change should fix the program. I don't
understand why other temporaries don't end up crashing the program.
For example the temporary generated with the line "return Expr3<Vec4,
Expr, MultOp>(*this, e)"
Could someone clear this up for me? I'm really lost.
Also, could someone give me any critique as to any fundamental design
flaws of the code above? Or any other errors or undesirable code they
see?
Thanks,
Asfand Yar