
"David Abrahams" wrote
Since "as expected" is vague, and your statement seems a little too sweeping, I'll say it this way:
I (Dave) think, but can't say for sure, that Andy wants plus to always return an int_ specialization when all the inputs are specializations of int_.
The as expected part is important and necessarily vague because the subject of the thread is basically about why mpl doesnt work as the OP expects. User expectations are often vague, but this one is consistent from quite a few people. ( Its mentioned in passing in the mpl book AFAIK). The expectation ( based on OP's light reading of examples I guess ) is this assert( boost::is_same < mpl::transform< vector_c<int,1,2,3> ,vector_c<int,1,1,1> ,some_plus_func > ::type , vector_c<int,2,3,4> >::value == true); Personally I think ( even ) that is with (some mods) a realistic expectation. The above would make sense if vector_c was a standalone type rather than an *interface* to vector. The act of doing that would introduce complexities sure because it would be necessary to specify the semantics. To make the above work some_plus_func would presumably need to look like template <int A,int B> some_plus_func; or template <typename T,T A,T B> some_plus_func; I think its possible to specialise transform to pick this up. Instead of the type placeholders you would use arbitrary constants ( <0,0> )here: assert( boost::is_same < mpl::transform< vector_c<int,1,2,3> ,vector_c<int,1,1,1> ,some_plus_func<0,0> > ::type , vector_c<int,2,3,4> >::value == true); Anyway if not possible, and for consistency call it transform_c Of course If vector_c was a standalone type then a function e.g 'to_vector' to convert to a mpl::vector would be required to get the current behaviour assert(boost::is_same< mpl::to_vector< long_<1>,vector_c<int,1,2,3,4> >::type, mpl::vector<long_<1>,long_<2>,long_<3>, long_<4> >
::value == true);
Anyway the point is I dont think its impossible to come up with an alternative design as you seem to be suggesting. But (Maybe more realistically) the same issues crops up with mpl::int_ assert( boost::is_same < mpl::plus< int_<1>, int_<1> > ::type , int_<2> >::value == true); Again I think thats a reasonable expectation, but it fails But in both cases the mpl designers argument is that these are only interfaces ,designed to save a bit of typing. My problem with this argument is that (as it stands) they are an input only interface and so when the type is regurgitated as error messages or when using comparisons etc one is presented with something "conceptually identical" as far as the designers are concerned but that has been the result of what seem to the user like arbitary transformations. Thats not pleasant. To the uninitiated it just looks like somethings gone wrong with the calculation. In case of int_, long_ etc ( and vector_c for that matter) the ideal would be for the above assertion to hold. int_'s and long_'s should be standalone types which have their own semantics. I think its not too difficult to add rules for how they interact with integral_c as well. As it stands mpl::plus assumes everythings an integral constant and perversely it actually reinforces that in code by giving back an integral_c whatever the actual integral_constant inputs are. This as well as seeming arbitrary, makes int_'s and long_'s and vector_c basically superfluous IMO. The current definition of mpl::plus (et al) strikes me as odd too with its tight coupling and assumption that its operands are integral-constants. plus and other arithmetic ops could be 'just an operator' with the result type solely dependent on the operands. I remember you arguing against this for mpl.. "concept overloading" was it? but cant remember why I'm out of time for now. Apologies that the above isnt as clear as I would like. regards Andy Little