| Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
| Version 1.9 Build 803 |
|
This problem is particularly endemic in the Arrays module and for these classes a particular solution has been devised. The Array class (and hence derived classes) have an upcasting member function called arrayCast() (or ac() for short).
For example in the aips/Arrays/ArrayMath.h class there is a function
T max(const Array<T> &a)which will not compile when called with a vector as an argument. ie.
Vector<Float> vec(4); cout << max(vec) << endl; // error flagged on this line!but will compile if rewritten as:
cout << max(vec.arrayCast()) << endl;
This solution gets particularly useful when doing arithmetic on Vectors because g++ will complain about:
Vector<Float> v1(4), v2(4); v1 += v2;And this should be changed to
v1.arrayCast() += v2.arrayCast(); // make the cast explicit or v1.ac() += v2.ac(); // emphasize the arithmetic not the cast
This problem has also been recently seen in the Lattice classes and a corresponding set of member functions called latticeCast(), or lc() for short, have been written.
On rare occasions you may need to selectively do an upcast when a templated argument can be either a builtin data type (Int/Float etc.) or an Array (Vector/Matrix etc.). For these occasions the functions at_c() & at_cc() exist. These global functions only upcast Arrays and leave the builtin data types alone. They are defined in the Array, Vector, Matrix & Cube classes7.1, and in aips.h for the builtin data types (and in String.h also).
The difference between the two functions is that at_c() is takes a non-constant input arguement while at_cc() takes a constant input arguement. Two function names are used rather than overloading just one because of what we think is a bug in the g++ compiler.
An example of this function in use in is the Measures module where a Quantum has standard templates of Double and Vector<Double>. Then the floor function is defined in QMath.cc as:
template <class Qtype>
Quantum<Qtype> floor(const Quantum<Qtype> &left) {
Qtype tmp = left.getValue();
Qtype ret;
at_c(ret) = floor(at_c(tmp));
return (Quantum<Qtype>(ret,left));
}
If you see this problem in other class hierarchies, you can do an explicit type cast but are instead urged to create an upcasting member function in the base class. The advantage of using member functions, rather than explicit casts, is that if g++ is ever able to do upcasts in the future it will then be easier to search for the upcasting functions and remove them. Please tell me if you do this, so I can add it to the documentation.
It is expected that this bug will disappear in g++ version 2.8.0 (private communication between Brian and one of the g++ developers).