Partially specialize a function template

Discussion in 'C++' started by mathieu, May 15, 2008.

  1. mathieu

    mathieu Guest

    Hi there,

    I know this is not possible in c++. So my question, how should I
    rewrite the following piece of code (without using a dummy class which
    template parameter could be use for partial specialization).

    template <typename TOut, typename TIn>
    void InverseRescaleFunction(TOut *out, const TIn *in, double
    intercept, double slope, size_t size)
    { ... }
    template <typename TOut>
    void InverseRescaleFunction(TOut *out, const float *in, double
    intercept, double slope, size_t size)
    { ... }



    Thanks !
    mathieu, May 15, 2008
    #1
    1. Advertising

  2. mathieu

    mathieu Guest

    On May 15, 12:48 pm, mathieu <> wrote:
    > Hi there,
    >
    > I know this is not possible in c++. So my question, how should I
    > rewrite the following piece of code (without using a dummy class which
    > template parameter could be use for partial specialization).
    >
    > template <typename TOut, typename TIn>
    > void InverseRescaleFunction(TOut *out, const TIn *in, double
    > intercept, double slope, size_t size)
    > { ... }
    > template <typename TOut>
    > void InverseRescaleFunction(TOut *out, const float *in, double
    > intercept, double slope, size_t size)
    > { ... }
    >
    > Thanks !


    Ok found a solution:

    http://www.gotw.ca/publications/mill17.htm

    ....
    // Example 4: Illustrating Moral #2
    //
    template<class T>
    struct FImpl;

    template<class T>
    void f( T t ) { FImpl<T>::f( t ); } // users, don't touch this!

    template<class T>
    struct FImpl
    {
    static void f( T t ); // users, go ahead and specialize this
    };
    ....

    Sorry for the noise
    -M
    mathieu, May 15, 2008
    #2
    1. Advertising

  3. mathieu

    mathieu Guest

    On May 15, 1:21 pm, mathieu <> wrote:
    > On May 15, 12:48 pm, mathieu <> wrote:
    >
    >
    >
    > > Hi there,

    >
    > > I know this is not possible in c++. So my question, how should I
    > > rewrite the following piece of code (without using a dummy class which
    > > template parameter could be use for partial specialization).

    >
    > > template <typename TOut, typename TIn>
    > > void InverseRescaleFunction(TOut *out, const TIn *in, double
    > > intercept, double slope, size_t size)
    > > { ... }
    > > template <typename TOut>
    > > void InverseRescaleFunction(TOut *out, const float *in, double
    > > intercept, double slope, size_t size)
    > > { ... }

    >
    > > Thanks !

    >
    > Ok found a solution:
    >
    > http://www.gotw.ca/publications/mill17.htm
    >
    > ...
    > // Example 4: Illustrating Moral #2
    > //
    > template<class T>
    > struct FImpl;
    >
    > template<class T>
    > void f( T t ) { FImpl<T>::f( t ); } // users, don't touch this!
    >
    > template<class T>
    > struct FImpl
    > {
    > static void f( T t ); // users, go ahead and specialize this};
    >
    > ...
    >
    > Sorry for the noise
    > -M


    For reference:

    template<typename TOut, typename TIn>
    struct FImpl;

    template<typename TOut, typename TIn>
    void InverseRescaleFunction(TOut *out, const TIn *in, double
    intercept, double slope, size_t size)
    { FImpl<TOut,TIn>::InverseRescaleFunction(out,in,intercept,slope,size); } //
    users, don't touch this!

    template<typename TOut, typename TIn>
    struct FImpl
    {
    static void InverseRescaleFunction( TOut *out, const TIn *in,
    double intercept, double slope, size_t size) // users, go ahead
    and specialize this
    {
    ....
    }
    };

    template<typename TOut>
    struct FImpl<TOut, float>
    {
    static void InverseRescaleFunction(TOut *out, const float *in,
    double intercept, double slope, size_t size)
    {
    ....
    }
    };

    -M
    mathieu, May 15, 2008
    #3
  4. mathieu

    Greg Herlihy Guest

    On May 15, 3:48 am, mathieu <> wrote:
    >
    >   I know this is not possible in c++. So my question, how should I
    > rewrite the following piece of code (without using a dummy class which
    > template parameter could be use for partial specialization).
    >
    > template <typename TOut, typename TIn>
    > void InverseRescaleFunction(TOut *out, const TIn *in, double
    > intercept, double slope, size_t size)
    > { ... }
    > template <typename TOut>
    > void InverseRescaleFunction(TOut *out, const float *in, double
    > intercept, double slope, size_t size)
    > { ... }


    I'm wondering how you happen to know that the above pair of function
    declarations is not possible in C++? Did you try using them in a C++
    program? For example:

    #include <iostream>

    template <typename TOut, typename TIn>
    void InverseRescaleFunction(TOut *out, const TIn *in, double
    intercept, double slope, size_t size)
    {
    std::cout << "InverseRescaleFunction<TOut, TIn>\n";
    }

    template <typename TOut>
    void InverseRescaleFunction(TOut *out, const float *in, double
    intercept, double slope, size_t size)
    {
    std::cout << "InverseRescaleFunction<TOut>\n";
    }

    int main()
    {
    float f = 139.4;
    int i;
    long o;

    InverseRescaleFunction(&i, &o, 2.2, 3.3, 4);
    InverseRescaleFunction(&i, &f, 2.2, 3.3, 4);
    }

    Did your version of the above program fail to compile or did it
    compile, run and produce the expected output shown below - as it did
    on my machine?

    Program Output:

    InverseRescaleFunction<TOut, TIn>
    InverseRescaleFunction<TOut>

    Greg
    Greg Herlihy, May 15, 2008
    #4
  5. mathieu

    mathieu Guest

    On May 15, 1:32 pm, Greg Herlihy <> wrote:
    > On May 15, 3:48 am, mathieu <> wrote:
    >
    >
    >
    > > I know this is not possible in c++. So my question, how should I
    > > rewrite the following piece of code (without using a dummy class which
    > > template parameter could be use for partial specialization).

    >
    > > template <typename TOut, typename TIn>
    > > void InverseRescaleFunction(TOut *out, const TIn *in, double
    > > intercept, double slope, size_t size)
    > > { ... }
    > > template <typename TOut>
    > > void InverseRescaleFunction(TOut *out, const float *in, double
    > > intercept, double slope, size_t size)
    > > { ... }

    >
    > I'm wondering how you happen to know that the above pair of function
    > declarations is not possible in C++? Did you try using them in a C++
    > program? For example:
    >
    > #include <iostream>
    >
    > template <typename TOut, typename TIn>
    > void InverseRescaleFunction(TOut *out, const TIn *in, double
    > intercept, double slope, size_t size)
    > {
    > std::cout << "InverseRescaleFunction<TOut, TIn>\n";
    > }
    >
    > template <typename TOut>
    > void InverseRescaleFunction(TOut *out, const float *in, double
    > intercept, double slope, size_t size)
    > {
    > std::cout << "InverseRescaleFunction<TOut>\n";
    > }
    >
    > int main()
    > {
    > float f = 139.4;
    > int i;
    > long o;
    >
    > InverseRescaleFunction(&i, &o, 2.2, 3.3, 4);
    > InverseRescaleFunction(&i, &f, 2.2, 3.3, 4);
    > }
    >
    > Did your version of the above program fail to compile or did it
    > compile, run and produce the expected output shown below - as it did
    > on my machine?
    >
    > Program Output:
    >
    > InverseRescaleFunction<TOut, TIn>
    > InverseRescaleFunction<TOut>
    >


    Hi Greg

    Indeed I tried your example and it actually produce the expected
    results. However my full code, available at:

    http://gdcm.svn.sourceforge.net/vie...torageAndFileFormat/gdcmRescaler.cxx?view=log

    Did not work as expected. The only difference is that there was an
    extra level of indirection. I'll work on your example to try to
    reproduce the issue I was having with version 3163:

    http://gdcm.svn.sourceforge.net/vie...at/gdcmRescaler.cxx?revision=3163&view=markup

    Thanks
    -Mathieu
    mathieu, May 15, 2008
    #5
  6. mathieu

    Greg Herlihy Guest

    On May 15, 5:22 am, mathieu <> wrote:
    > On May 15, 1:32 pm, Greg Herlihy <> wrote:
    >
    >
    >
    > > On May 15, 3:48 am, mathieu <> wrote:

    >
    > > >   I know this is not possible in c++. So my question, how should I
    > > > rewrite the following piece of code (without using a dummy class which
    > > > template parameter could be use for partial specialization).

    >
    > > > template <typename TOut, typename TIn>
    > > > void InverseRescaleFunction(TOut *out, const TIn *in, double
    > > > intercept, double slope, size_t size)
    > > > { ... }
    > > > template <typename TOut>
    > > > void InverseRescaleFunction(TOut *out, const float *in, double
    > > > intercept, double slope, size_t size)
    > > > { ... }

    >
    > > I'm wondering how you happen to know that the above pair of function
    > > declarations is not possible in C++? Did you try using them in a C++
    > > program? For example:

    >
    > >     #include <iostream>

    >
    > >     template <typename TOut, typename TIn>
    > >     void InverseRescaleFunction(TOut *out, const TIn *in, double
    > >     intercept, double slope, size_t size)
    > >     {
    > >         std::cout << "InverseRescaleFunction<TOut, TIn>\n";
    > >     }

    >
    > >     template <typename TOut>
    > >     void InverseRescaleFunction(TOut *out, const float *in, double
    > >     intercept, double slope, size_t size)
    > >     {
    > >         std::cout << "InverseRescaleFunction<TOut>\n";
    > >     }

    >
    > >     int main()
    > >     {
    > >         float f = 139.4;
    > >         int i;
    > >         long o;

    >
    > >         InverseRescaleFunction(&i, &o, 2.2, 3.3, 4);
    > >         InverseRescaleFunction(&i, &f, 2.2, 3.3, 4);
    > >     }

    >
    > > Did your version of the above program fail to compile or did it
    > > compile, run and produce the expected output shown below - as it did
    > > on my machine?

    >
    > >     Program Output:

    >
    > >     InverseRescaleFunction<TOut, TIn>
    > >     InverseRescaleFunction<TOut>

    >
    > Hi Greg
    >
    >   Indeed I tried your example and it actually produce the expected
    > results. However my full code, available at:
    >
    > http://gdcm.svn.sourceforge.net/viewvc/gdcm/trunk/Source/MediaStorage...
    >
    >   Did not work as expected. The only difference is that there was an
    > extra level of indirection. I'll work on your example to try to
    > reproduce the issue I was having with version 3163:
    >
    > http://gdcm.svn.sourceforge.net/viewvc/gdcm/trunk/Source/MediaStorage...


    It is true that a function template cannot be partially specialized in
    C++. But there is little reason why a C++ program would ever need to.
    A C++ program can always overload a function with more than one
    function template (just like the two function templates in your
    original example overload the "InverseRescaleFunction" function). And
    whenever multiple function templates overload the same function, the C+
    + compiler applies the rules of "partial ordering" to select the best
    function template to match a particular function call.

    So I do not think any particularly clever techniques are needed in
    this situation. Simply declare the function templates that are needed
    - and let the C++ compiler pick the best one to call.

    Greg
    Greg Herlihy, May 15, 2008
    #6
    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. Old Wolf
    Replies:
    4
    Views:
    369
    Victor Bazarov
    Apr 8, 2005
  2. mrstephengross
    Replies:
    1
    Views:
    275
    Victor Bazarov
    Aug 2, 2005
  3. sebastian
    Replies:
    1
    Views:
    274
  4. Replies:
    5
    Views:
    596
  5. Pavel
    Replies:
    2
    Views:
    238
    Pavel
    Aug 22, 2010
Loading...

Share This Page