
On Wed, 28 Jun 2006 23:38:25 -0400, David Abrahams <dave@boost-consulting.com> wrote:
I never solved that problem... until today. The enclosed works. It could probably be considerably simplified if you untwist the logic a bit. In particular, you could probably find a way to get rid of remove_bounds. The basic idea here is that the only way to force an error in some contexts, with vc6, is at the top level, with eval0<...>::not_array being a nonexistent type.
Yes. As you say, "in some contexts". I realize that this is more an issue of compiler workarounds than template metaprogramming per se. I mean: you can get rid of remove_bounds<> and/or implement your is_array with something like this (not thoroughly tested): namespace xyz { // my usual conversion burning -gps struct burn { burn(const volatile void *); }; template <typename t> void is_array (t*, t* const volatile *); char is_array (burn ...); } Now, sizeof(xyz::is_array(e, &e)) should either produce an error or yield 1 (I may be missing something and the above might not work at all, but that's not the point). This is basically what I had used in my pp based solution, as, building upon, it you can easily generate for instance 1*1*1* sizeof(a[0][0]) / sizeof(a[0][0][0]) The point is: will xyz::is_array() do its job correctly in complex metaprogramming invocations? If you prefer "in all contexts"? A look at the mpl sources shows that they really make somersaults (well, let me use this word again :)) to hide compiler idiosyncracies (certainly our is_array<> is nothing as simple as the above). So, to make a long story short, I'm a bit reluctant to remove array_bounds<> or mpl::eval_if_c or anything else, because they are a thoroughly tested ground to build upon for broken compilers. And then all this *is* for broken compilers, as for conforming ones the whole utility is a few lines of code (my initial attachment). I'm refining your solution a bit and writing more tests, then if we agree on this I'll ask for a fast-track review. In the meantime I'd like to ask one question: * Any reason why you used mpl::identity<empty> instead of mpl::identity<>? does the latter break on some known compiler? I'm asking because it could be the reverse and that using the default (i.e. boost::mpl::na) is the preferred/most reliable way. My guess is that you just wanted to have a clearer diagnostic message, but I wanted to ask. --Gennaro.