|
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