Hi, On 1/3/25 3:41 PM, Stefan Weinzierl wrote:
ex g = pow(x,5); [...] g.print(GiNaC::print_context(std::cout)); std::cout << std::endl;
will print [...] [power object]
Is that really intentional? The behaviour is the same in GiNaC 1.8.7 and 1.8.8.
Well.... Class 'print_context' is the common base class for 'print_dflt', 'print_latex', 'print_csrc', etc. I am not sure if it makes sense to use it. After all, there are ostream manipulator 'dflt', 'latex', and 'csrc' (operators.h), but none for 'print_context'. On the other hand, 'print_context' is totally public. What happens is: The lookup implemented in basic::print_dispatch() doesn't find a method in the print dispatch table for print_default for class 'power'. So it proceeds to class 'basic', the base class of 'power' to look for a dispatch function and this is the one printing "[power object]". The fine user manual cares to elaborate (in section 6.3 "GiNaC's expression output system"): The method table contains one slot for each possible ‘print_context’ type, indexed by the (internally assigned) serial number of the type. Slots may be empty, in which case GiNaC will retry the method lookup with the ‘print_context’ object's parent class, possibly repeating the process until it reaches the ‘print_context’ base class. If there's still no method defined, the method table of the algebraic object's parent class is consulted, and so on, until a matching method is found (eventually it will reach the combination ‘basic/print_context’, which prints the object's class name enclosed in square brackets). You can think of the print methods of all the different classes and output formats as being arranged in a two-dimensional matrix with one axis listing the algebraic classes and the other axis listing the ‘print_context’ classes. And it turns out that class 'power' has all kinds of output methods except 'print_tree' and 'print_context'! If we change the existing method for 'print_dflt' to be the one for 'print_context', your code will work as you expected: The lookup for 'print_dflt' will find the base method for 'print_context'. One last piece to do would be to add a method for 'print_tree' because our new method for 'print_context' will match this one while before we were using the one from class 'basic'. The attached patch does that. I'm unsure if this is patch is right. I guess it depends on whether your code using 'print_context' directly is right or not. Comments welcome! -richy. PS: The patch breaks the ABI, but that ain't grave. I think that the alternative of making 'print_context' abstract would break the API and that would be worse. -- Richard B. Kreckel <https://in.terlu.de/~kreckel/>