Return type autodetection in templates

Discussion in 'C++' started by Tim Wesson, Jul 8, 2003.

  1. Tim Wesson

    Tim Wesson Guest

    Does anyone know if it is possible to choose between the below
    templates (or similar ones) according to the promotion rules for
    types T and U?

    Thanks,

    Tim Wesson.

    [...]

    template<typename T, typename U>
    inline matrix<T> operator+(const matrix<T>& m, const matrix<U>& n)
    { return matrix<T> (m) += n; }

    template<typename T, typename U>
    inline matrix<U> operator+(const matrix<T>& m, const matrix<U>& n)
    { return matrix<U> (m) += n; }

    int main (void)
    {
    matrix<double> matd1, matd2;
    matrix<float> matf1, matf2;

    cout << matd1 * matf1 << '\n'; // should print matrix<double> ...
    cout << matf2 * matd2 << '\n'; // should print matrix<double> ...
    }
     
    Tim Wesson, Jul 8, 2003
    #1
    1. Advertising

  2. In article <>, Tim Wesson
    <> wrote:

    | Does anyone know if it is possible to choose between the below
    | templates (or similar ones) according to the promotion rules for
    | types T and U?
    |
    | Thanks,
    |
    | Tim Wesson.
    |
    | [...]
    |
    | template<typename T, typename U>
    | inline matrix<T> operator+(const matrix<T>& m, const matrix<U>& n)
    | { return matrix<T> (m) += n; }
    |
    | template<typename T, typename U>
    | inline matrix<U> operator+(const matrix<T>& m, const matrix<U>& n)
    | { return matrix<U> (m) += n; }
    |
    | int main (void)
    | {
    | matrix<double> matd1, matd2;
    | matrix<float> matf1, matf2;
    |
    | cout << matd1 * matf1 << '\n'; // should print matrix<double> ...
    | cout << matf2 * matd2 << '\n'; // should print matrix<double> ...
    | }

    You can sort of do this today. But it doesn't scale well if you have
    lots of different types to combine. For just float and double you
    might try something like:

    template <class T, class U> struct promote;
    template <> struct promote<double, double> {typedef double type;};
    template <> struct promote<double, float> {typedef double type;};
    template <> struct promote<float, double> {typedef double type;};
    template <> struct promote<float, float> {typedef float type;};

    template<typename T, typename U>
    inline
    matrix<typename promote<T,U>::type>
    operator+(const matrix<T>& m, const matrix<U>& n)
    {
    matrix<typename promote<T,U>::type> temp(m);
    temp += n;
    return temp;
    }

    This also shows a potential optimization: Assuming matrix::eek:perator+=
    returns a matrix&, don't return that. Instead return the temp directly
    as shown above. The former disables return value optimization. The
    latter does not.

    If you happen to be running on gnu, or Metrowerks CodeWarrior, you
    might try __typeof__:

    template<typename T, typename U>
    inline
    matrix<__typeof__(T() + U())>
    operator+(const matrix<T>& m, const matrix<U>& n)
    {
    matrix<__typeof__(T() + U())> temp(m);
    temp += n;
    return temp;
    }

    This scales better, but isn't standard. However the committee is hotly
    debating a typeof-like animal for C++0X.

    --
    Howard Hinnant
    Metrowerks
     
    Howard Hinnant, Jul 8, 2003
    #2
    1. Advertising

  3. Tim Wesson

    Tim Wesson Guest

    Howard Hinnant <> wrote in message news:<080720031112342430%>...
    > In article <>, Tim Wesson
    > <> wrote:
    >
    > | Does anyone know if it is possible to choose between the below
    > | templates (or similar ones) according to the promotion rules for
    > | types T and U?
    > |
    > | Thanks,
    > |
    > | Tim Wesson.
    > |
    > | [...]
    > |
    > | template<typename T, typename U>
    > | inline matrix<T> operator+(const matrix<T>& m, const matrix<U>& n)
    > | { return matrix<T> (m) += n; }
    > |
    > | template<typename T, typename U>
    > | inline matrix<U> operator+(const matrix<T>& m, const matrix<U>& n)
    > | { return matrix<U> (m) += n; }
    > |
    > | int main (void)
    > | {
    > | matrix<double> matd1, matd2;
    > | matrix<float> matf1, matf2;
    > |
    > | cout << matd1 * matf1 << '\n'; // should print matrix<double> ...
    > | cout << matf2 * matd2 << '\n'; // should print matrix<double> ...
    > | }
    >
    > You can sort of do this today. But it doesn't scale well if you have
    > lots of different types to combine. For just float and double you
    > might try something like:
    >
    > template <class T, class U> struct promote;
    > template <> struct promote<double, double> {typedef double type;};
    > template <> struct promote<double, float> {typedef double type;};
    > template <> struct promote<float, double> {typedef double type;};
    > template <> struct promote<float, float> {typedef float type;};
    >
    > template<typename T, typename U>
    > inline
    > matrix<typename promote<T,U>::type>
    > operator+(const matrix<T>& m, const matrix<U>& n)
    > {
    > matrix<typename promote<T,U>::type> temp(m);
    > temp += n;
    > return temp;
    > }
    >
    > This also shows a potential optimization: Assuming matrix::eek:perator+=
    > returns a matrix&, don't return that. Instead return the temp directly
    > as shown above. The former disables return value optimization. The
    > latter does not.
    >
    > If you happen to be running on gnu, or Metrowerks CodeWarrior, you
    > might try __typeof__:
    >
    > template<typename T, typename U>
    > inline
    > matrix<__typeof__(T() + U())>
    > operator+(const matrix<T>& m, const matrix<U>& n)
    > {
    > matrix<__typeof__(T() + U())> temp(m);
    > temp += n;
    > return temp;
    > }
    >
    > This scales better, but isn't standard. However the committee is hotly
    > debating a typeof-like animal for C++0X.


    Thankyou, this is as good an answer as I could hope for. I'm just getting
    to grips with C++, hence the attempt to write a generic matrix program.
     
    Tim Wesson, Jul 9, 2003
    #3
  4. Tim Wesson

    Tim Wesson Guest

    On Wed, 09 Jul 2003 07:09:50 -0700, Tim Wesson wrote:

    > Howard Hinnant <> wrote in message news:<080720031112342430%>...


    [...]

    >> If you happen to be running on gnu, or Metrowerks CodeWarrior, you
    >> might try __typeof__:
    >>
    >> template<typename T, typename U>
    >> inline
    >> matrix<__typeof__(T() + U())>
    >> operator+(const matrix<T>& m, const matrix<U>& n)
    >> {
    >> matrix<__typeof__(T() + U())> temp(m);
    >> temp += n;
    >> return temp;
    >> }
    >>
    >> This scales better, but isn't standard. However the committee is hotly
    >> debating a typeof-like animal for C++0X.

    >
    > Thankyou, this is as good an answer as I could hope for. I'm just getting
    > to grips with C++, hence the attempt to write a generic matrix program.


    Sadly this doesn't work using g++. Still, nice to know it's in the
    pipeline!

    http://gcc.gnu.org/PR11578

    Cheers,

    Tim Wesson
     
    Tim Wesson, Jul 19, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Benny

    FOAF autodetection

    Benny, Oct 5, 2003, in forum: XML
    Replies:
    0
    Views:
    357
    Benny
    Oct 5, 2003
  2. JKop
    Replies:
    3
    Views:
    492
  3. lux

    proxy autodetection

    lux, Sep 9, 2004, in forum: Python
    Replies:
    0
    Views:
    285
  4. recover
    Replies:
    2
    Views:
    832
    recover
    Jul 25, 2006
  5. Christopher
    Replies:
    1
    Views:
    416
    Christopher Pisz
    Jan 29, 2008
Loading...

Share This Page