Boost logo

Boost :

From: William Kempf (sirwillard_at_[hidden])
Date: 2000-10-26 12:30:34


Just to let everyone know what I've found lately while attempting to
use the "hacks" discussed here to get a tuple on VC6.

Though the recent "hacks" at first appear promising (and in fact they
may help with limited problem domains) they aren't going to do us
much good as a general work around. VC6 has more troubles than just
poor conformance with the standard with regards to no partial
template specialization. It's also riddled with parsing and
generation bugs. The simplest illustration I can give for a dreadful
parsing bug can be reduced down to the following example program:

#include <boost\call_traits.hpp>

template <typename T1, typename T2>
void test(boost::call_traits<T1>::param_type p1,
   boost::call_traits<T2>::param_type p2)
{
        p1 = p2; // Just something stupid to insure full parsing.
}

int main()
{
        test(10, 'c');
        return 0;
}

Attempting to compile this results in the following:

Compiling...
main.cpp
D:\Projects\Tuple\main.cpp(12) : error C2782: 'void __cdecl test
(const T1 &,const T1 &)' : template parameter 'T1' is ambiguous
        could be 'char'
        or 'int'
Error executing cl.exe.

Tuple.exe - 1 error(s), 0 warning(s)

The error is dumbfounding. Obviously the parser has failed miserably
here, using T1 for both parameters despite the fact that the actual
code used T1 and T2.

Even stranger, the (partial) class below illustrates how nearly
identical template constructs are used for a constructor and an
assignment operator but when compiled VC6 accepts only the
constructor (can be varified by commenting out the assignment
operator).

template <typename T1, typename T2=detail::nil,
   typename T3=detail::nil, typename T4=detail::nil>
struct tuple : detail::to_cons<T1, T2, T3, T4>::cons
{
   typedef typename detail::to_cons<T1, T2, T3, T4>::cons inherited;

   template <typename H, typename T>
   tuple(const detail::cons<H, T>& u)
      : inherited(u)
   {
   }

   template <typename H, typename T>
   tuple<T1, T2, T3, T4>& operator=(const detal::cons<H, T>& v)
   {
      inherited::operator=(v);
      return *this;
   }
};

The error message reported? The infamous INTERNAL COMPILER ERROR.
Simplifying the assignment template by returning void, even changing
it from an operator to an "assign" method and leaving the
implementation as a no-op empty definition, doesn't help the compiler
out.

With some creative coding I've gotten the tuple to mostly work, but
the tie() method is non-operational. Despite specifying reference
types for the tuple created, the assignment does not bind the results
back to the tied variables. I've stared at this long enough that I
honestly think it's a generation bug on the part of VC6 and not a
mistake I made in the code, but since I've also been fighting these
other issues I suppose it may be a bug on my behalf. In any event,
though partially implemented, I wouldn't trust this code, nor do I
think it addresses all of the issues that the original tuple
implementation tried to address (ref-to-ref issues, etc.). However,
at this point I think I give up on VC6. I hope that VC7 fixes enough
things that even with out partial specialization we can get a working
tuple, but I wouldn't suggest anyone hold their breath.

In the mean time, if anyone else is interested in taking a hack at
making tuples work in VC6 I'd be happy to share what I have and the
experiences I've had. I'd also be intersted in receive the VC7 beta
from someone who has it (I know you can d/l it, but the install you
d/l requires Win2k to run and I'm only running NT4 and 98 at the
moment). With VC7 I might be able to make a better go at this.

Bill Kempf


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk