Blitz logo

Blitz Support :

From: Julian Cummings (cummings_at_[hidden])
Date: 2003-09-11 15:58:08


Julian Cummings wrote:

> Hi Matthias,
>
> This *should* already work, but it doesn't because of a namespace
> problem. The standard C math functions for the blitz::Array type are
> defined in namespace blitz, and they apply the math function to each
> element of the Array. But they do this by calling the math function
> with the proper namespace qualifier (usually std::). Applying
> std::conj() to a TinyVector fails because this function is defined in
> namespace blitz, not namespace std.
>
> I am not sure what is the best way to solve this problem. One
> solution would be to invoke math functions on Array elements without
> the std:: qualifier when defining their behavior
> for blitz Arrays. I think this is OK because in <blitz/blitz.h> we
> already include both <cmath> (if available) and <math.h> and then
> import the symbols from namespace std into
> namespace blitz. So the standard math functions should be found
> without any qualifier.
> I'll give this approach a try and see if it is a safe and effective
> solution.
>
Sadly, this approach does not seem to work. I think I looked at this
namespace problem
once before and wasn't able to solve it. The trouble is with the rules
for function name
lookup in C++. If you use non-qualified names like I was suggesting
above, then the
compiler will look in the current scope first, followed by any enclosing
scopes, followed
by the scope in which the function arguments are defined. With a using
directive like
"using namespace std;" you can bring function names from the std
namespace into the
current scope, but functions actually defined in the current scope still
take precedence
over the imported ones if there is a name clash. Only with a using
declaration such as
"using std::sqrt;" can you force the imported function to take precedence.

So if you are in namespace blitz defining a standard math function like
sqrt() acting on
a blitz Array, you want to apply sqrt() to each Array element. If you
apply it without
the std:: qualifier, it will fail for built-in element types because the
compiler tries to
apply versions of sqrt() defined within the blitz namespace first. If
you apply std::sqrt(),
it will fail for TinyVector elements because that version of sqrt() is
not in namespace std.

Maybe what is needed here is a traits class to indicate if an element is
a built-in type or not.
I will look into this possibility ...

Regards, Julian C.

-- 
Dr. Julian C. Cummings                       E-mail: cummings_at_[hidden]
California Institute of Technology           Phone:  626-395-2543
1200 E. California Blvd., Mail Code 158-79   Fax:    626-584-5917
Pasadena, CA 91125