
Hello, I'm pleased to see so much activity in the development of Boost.Units recently. I try to apply it myself in some code to model physical systems. There it helps me a lot to ensure the correct use of the model parameters inside the model equations and to ensure the correct composition of components to a system model. Certain component behaviour, I would like to parametrize for each component instance by passing a functor describing, e.g., a signal waveform or a non-linear relation between to quantities. I therefore tried to combine Boost.Units with Boost.Lambda and Boost.Function. I noticed that currently Units and Lambda use two independent systems of trait classes to determine the return type of algebraic operations like +, -, *, /. This requires to litter the lambda expression with a lot of ret<return_type>(...) function calls to construct a functor containing boost::units::quantity<U, V> instances. However, the trait classes used by Units and Lambda are very similar, so I created as a first solution a header file <lambda.hpp> (see attachment), which extends Boost.Lambda's return type reduction system through partial specialization to use Boost.Units' trait classes in case boost::unit::quantity<U,V> are involved in operator[+|-|*|/]() calls. Maybe it's also useful for others and could even become part of Boost.Units after some further improvements. However, there are some open issues: - Can some of the partial specializations be dropped? - Is there a need to add other specializations (e.g, for boost::units::unit<Dim, System, Enable>)? - Is there a way to work around boost::lambda:bind's limitation concerning the binding of overloaded functions? The required static_cast to the function pointer (referring, e.g., a function from boost/units/cmath.hpp) is tedious. The attached small test program <units_with_lambda_test.cpp> demonstrates its usage and tedious bind issue, for which I haven't found a solution yet. Boost.Lambda requires calls to functions to be postponed using boost::lambda::bind(), so that they are executed not only once upon functor creation but at each functor call. Bind has the unfortunate limitation that it cannot resolve calls to overloaded functions. Thus, each time a call to an overloaded function (e.g., all functions defined in <boost/units/cmath.hpp>) is made, a lengthy static_cast<return_type (*)(argument_type)>(function_name) is needed for the first bind argument to help the compiler to find the overloaded function, which can accept the function arguments passed by the other bind arguments. Could this be somehow avoided or at least the syntax simplified? I'm thinking of, e.g., a templated function or (more ugly) a preprocessor macro adding the required static_cast based on some trait class or typeof. I'm looking forward to your feedback. Best regards, Torsten Maehne .DEFAULT_GOAL := all # Install locations of Boost 1.35 and Boost.Units BOOSTROOT := /opt/boost_1_35_0 BOOSTUNITS := /opt/boost_units CPPFLAGS := -I$(BOOSTROOT)/boost/tr1/tr1 -I$(BOOSTROOT) -I$(BOOSTUNITS) CXXFLAGS := -g -Wall % : %.o $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ | c++filt .PHONY : all clean all : units_with_lambda_test units_with_lambda_test : units_with_lambda_test.o units_with_lambda_test.o : units_with_lambda_test.cpp lambda.hpp clean : -rm units_with_lambda_test *.o *~ semantic.cache