
Hi Matthias, On Apr 30, 9:17 am, Matthias Schabel <bo...@schabel-family.org> wrote:
Perhaps you would be willing to add the atomic system to the Boost distribution?
Seriously, I would love to. What is the best way to share the code and start the collaboration?
I expect that there is a reasonable subset of users for whom this would add value...
You don't imagine how many. I do quantum chemistry and it is incredible how your library changed the way I write my codes... With the certainty that the equations are dimensionally correct and that I am not messing up with the conversion factors I can concentrate in the real problem.
But for some formulas I would like to allow implicit conversion, for example when adding energies in SI and energies in atomic units (I don't care which direction the conversion is done since I will transform to one of the two at the end of the formula).
My recollection is that, after much debate, discussion, and contemplation, it was decided that allowing implicit conversions created too many problems and ambiguities, some of them subtle.
I understand, and I think the debate is not fruitless.
That being said, it is a common request for functions that take arbitrary units of specified dimension. This is relatively straightforward to accomplish
template<class Y,class System> void f(const quantity<unit<desired_dimension_type,System>,Y>& arg) { const quantity<desired_unit_to_use_for_internal_calculations,Y> q(arg); // do something with q return;
}
This doesn't solve your specific request for implicit assignment to work, but is the recommended way of doing "implicit" conversion in function arguments. Hope this helps.
Actually by looking at your code and my code I realized that it is unreasonable to ask for implicit conversion within normal ('=') assignment. In general assigment is not the cause of the unelegant code with explicit conversion but are the operations inside of a long equation what we should focus in. Besides, operator= can't be overloaded in C++. My example in the original post was misleading because in concentrated in the assignment rather than in the syntax improvement I wanted (mainly being able to add quantities in different systems). It seems that just by taking care of addition and substraction we have 90% of the problem solved, my approach was the following: overload binary operator+ and operator- in a special namespace (e.g. called "si_conversion" --suggestions accepted--). In such a way that the following code works: quantity<si::energy> een1(1.e-17*si::joules); quantity<atomic::energy> een2(2.*atomic::hartree); ---> using namespace boost::units::atomic::si_conversion; //"activates" implicit convertion on addition in the current scope quantity<atomic::energy> een3(een1+een2); // addition works here because operator+(si_unit, atomic_unit) is in scope and this is the code for operator+ and operator-, in principle should work for any physical dimension from atomic system to si system. namespace boost{ namespace units{ namespace atomic{ namespace si_conversion{ template<class Dimension, class Y> quantity<unit<Dimension, atomic::system>, Y> operator+( quantity<unit<Dimension, atomic::system>, Y> const& e1, quantity<unit<Dimension, si::system >, Y> const& e2 ){ return e1+quantity<unit<Dimension, atomic::system>, Y>(e2); // or e1 + (quantity<atomic::energy, Y>)e2; ??? } template<class Dimension, class Y> quantity<unit<Dimension, atomic::system>, Y> operator+( quantity<unit<Dimension, si::system >, Y> const& e1, quantity<unit<Dimension, atomic::system>, Y> const& e2 ){ return quantity<unit<Dimension, atomic::system>, Y>(e1)+e2; } template<class Dimension, class Y> quantity<unit<Dimension, atomic::system>, Y> operator-( quantity<unit<Dimension, atomic::system>, Y> const& e1, quantity<unit<Dimension, si::system >, Y> const& e2 ){ return e1-quantity<unit<Dimension, atomic::system>, Y>(e2); } template<class Dimension, class Y> quantity<unit<Dimension, atomic::system>, Y> operator-( quantity<unit<Dimension, atomic::system>, Y> const& e1, quantity<unit<Dimension, atomic::system>, Y> const& e2 ){ return quantity<unit<Dimension, atomic::system>, Y>(e1)-e2; } }}}} Thank you Alfredo