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[i] + i2[i];

}

};

struct MultOp

{

template<class I1, class I2> static inline float

call(size_t i, const I1& i1, const I2& i2)

{

return i1[i] * i2[i];

}

};

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)[i]

}

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

--

http://www.it-is-truth.org/