Here more a suggestion than a solution:

```
#include <iostream>
template <class T, int N> class Tuple; // forward decl
template <class T, int N, int M>
class TupleArgs {
public:
Tuple<T, N>* tuple;
Tuple<T, M>* uninitialized;
TupleArgs(Tuple<T, N>* t, Tuple<T, M>* u) : tuple(t), uninitialized(u) {}
};
template <class T, int N>
class Tuple {
public:
T head;
Tuple<T, N-1> tail;
Tuple() : head(0) {}
TupleArgs<T, N, N-1> operator=(T a) {
head = a;
return TupleArgs<T, N, N-1>(this, &tail);
}
Tuple<T, N>& operator=(const Tuple<T, N>& other) {
head = other.head;
tail = other.tail;
return *this;
}
};
template <class T>
class Tuple<T, 1> {
public:
Tuple<T, 1>() : head(0) {}
Tuple<T, 1>(T a) : head(a) {}
Tuple<T, 1>& operator=(const Tuple<T, 1>& other) {
head = other.head;
return *this;
}
T head;
};
template <class T, int N, int M>
TupleArgs<T, N, M-1> operator,(TupleArgs<T, N, M>& a, T b) {
a.uninitialized->head = b;
return TupleArgs<T, N, M-1>(a.tuple, &a.uninitialized->tail);
}
template <class T, int N>
Tuple<T, N>& operator,(TupleArgs<T, N, 1>& a, T b) {
a.uninitialized->head = b;
return *a.tuple;
}
int _tmain(int argc, _TCHAR* argv[])
{
Tuple<int, 3> triple;
triple = 4, 5, 6;
std::cout << triple.head << ' ' << triple.tail.head << ' ' << triple.tail.tail.head << ' ' << std::endl;
Tuple<int, 9> matrix33;
matrix33 = 1, 2, 0,
4, 5, 3,
7, 8, 2;
// use your debugger if you want to check that this really works
Tuple<int, 3> triple1, triple2;
//triple1 = triple2 = 1, 2, 3; // error: the left assignment tries to assign the
// result of (triple2 =1), which has the wrong type
//triple1 = (triple2 = 1, 2, 3); // ok, but ugly(
triple1 = 1, 2, 3;
triple2 = triple1;
return 0;
}
```

With int as T it works fine, with double as T it doesn't work.

Perhaps the upper mentioned compiler bug?

My environment : VS2010, SP1Rel

Best regards

The evaluation order is the least of my problems, but one that is indeed compiler-dependend. The standard says that the (built-in) comma operator must evaluate each operand left to right. But it also says that there is no guarantee for the order of evaluation of function arguments. By providing an overload function, the operands are now treated as function arguments, rather than a comma-separated sequence.

I actually expect most compilers will still evaluate all operands in correct order, but the standard doesn't enforce it. This has been discussed at stackoverflow and various other locations.

On a sidenote I just realized I accidentally posted my response as a solution. I deleted it and reposted my response correctly, but along with the solution I obliterated your response. For those who'd also want to take a look at Blitz, the link is http://sourceforge.net/projects/blitz/