Boost logo

Boost Users :

From: hicks (hicks_at_[hidden])
Date: 2002-05-03 09:51:10


Thanks. Code is below.

Member operator *() branches to a template functor which specializes
for arithmetic type, and leaves the rest undefined.

Later, the operator * still cannot be overloaded, but the as yet undefined
cases of the template functor are available to be defined.
So that is how the problem is solved.

I didn't want to use inheritance as that could profoundly affect
performance.

(In the atual code, A is a point type and Z is an affine transformation
type.
I want to be able to write
    a * z0 * z1 * z3,
etc.Otherwise I have to define Z * A and write
    z3 * (z2 * (z1*a)))
to bring about the same computation.)

[I also wanted to key the return type using type traits, but the
compiler complained about
invalid template argument list, but that's another story].

Craig Hicks

John Maddock wrote:

>>I know how to use type traits to enable compile time seperate procedures,
>>but not how to use it to define a procedure for some type and not others.
>>
>
>One way (for member functions) is to use inheritance: add an "implementation
>layer" that includes the member function or not depending on whether a trait
>is true or not:
>
>template <class T, bool b>
>struct mybase
>{
>// details
>T operator*();
>};
>
>template <class T, true>
>struct mybase
>{
>// details
>};
>
>template <class T>
>struct mine : public mybase<T, ::boost::is_arithmetic<T>::value>
>{
>// details
>};
>
>
>
>
>Info: <http://www.boost.org>
>Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl>
>Unsubscribe: <mailto:boost-users-unsubscribe_at_[hidden]>
>
>
>Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
>
>
>
#include <iostream>
#include "boost\type_traits.hpp"

///////////////////////////////////////////////////////////////////

template <class T>
struct A
{
    T i;

    template <class U>
    A<T>
    operator * (const U& u) const;
};

template <class T, class U, bool b>
struct AMultFtr
{
    A<T> operator()(const A<T>& a, const U& u) const;
};

template <class T, class U>
struct AMultFtr<T, U, true>
{
    A<T> operator()(const A<T>& a, const U& u) const
        { A<T> ra; ra.i = a.i * u; return ra;}
};

template <class T>
template <class U>
A<T> A<T>::operator * (const U& u) const
{
// A<U> a;
// a.i = i * u;
// return a;
    return AMultFtr<T, U, boost::is_arithmetic<U>::value>()(*this,u);
};

///////////////////////////////////////////////////////////////////

struct Z
{
    float x,y;
};

#if (0)
template <class T>
A<float> operator * (const A<T>& a, const Z& z)
    { A<float> ra; ra.i= a.i * z.x + z.y; return ra; }
#else
template <class T>
struct AMultFtr<T, Z, false>
{
    A<T> operator()(const A<T>& a, const Z& z) const
        { A<T> ra; ra.i= a.i * z.x + z.y; return ra; }
};
#endif

///////////////////////////////////////////////////////////////////

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
    A<int> a; a.i = 1;
    std::cout << (a*3.5).i << std::endl;

    Z z; z.x = 4.5; z.y = 5.5;
    std::cout << (a*z).i << std::endl;

    return 0;
}
//---------------------------------------------------------------------------


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net