What is the correct template syntax for this?

Discussion in 'C++' started by fabio_cannizzo@yahoo.com, Apr 1, 2009.

  1. Guest

    The following syntax cause gcc to complain about:
    - explicit specialization in non-namespace scope
    - enclosing class templates are not explicitly specialized

    So I guess that I need to put the specialization of foo<0> somewhere
    out of the class definition, but what is the correct syntax to do
    that?

    Thanks a lot

    template <class A>
    class MyClass
    {
    template <unsigned char N>
    void foo( sie_t int ) { /* ... */ }

    template <>
    void foo<0>( sie_t int ) { /* ... */ }
    };
     
    , Apr 1, 2009
    #1
    1. Advertising

  2. Guest

    In the previous messages there where a few typo. I rewrote better the
    code:

    template <class A>
    class MyClass
    {
    template <unsigned char N>
    void foo( int x )
    {
    // ... do something
    foo<N-1>( x );
    }

    template <>
    void foo<0>( int x )
    {
    // do nothing: stops template expansion recursion
    }
    };
     
    , Apr 1, 2009
    #2
    1. Advertising

  3. SG Guest

    On 1 Apr., 09:51, wrote:
    > The following syntax cause gcc to complain about:
    > - explicit specialization in non-namespace scope
    > - enclosing class templates are not explicitly specialized
    >
    > So I guess that I need to put the specialization of foo<0> somewhere
    > out of the class definition, but what is the correct syntax to do
    > that?


    Yes. Have you tried the namespace scope? :p

    struct S
    {
    template<int N>
    void foo(int k);
    };

    template<int N>
    void S::foo(int k) {}

    template<>
    void S::foo<0>(int k) {}


    Cheers!
    SG
     
    SG, Apr 1, 2009
    #3
  4. ZikO Guest

    SG wrote:
    > Yes. Have you tried the namespace scope? :p
    >
    > struct S
    > {
    > template<int N>
    > void foo(int k);
    > };
    >
    > template<int N>
    > void S::foo(int k) {}
    >
    > template<>
    > void S::foo<0>(int k) {}
    >
    >
    > Cheers!
    > SG


    Is this also possible for the template function in the template class ?

    Cheers!
    ZikO
     
    ZikO, Apr 1, 2009
    #4
  5. SG Guest

    On 1 Apr., 12:37, ZikO <> wrote:
    > SG wrote:
    > > Yes. Have you tried the namespace scope? :p

    >
    > >   struct S
    > >   {
    > >      template<int N>
    > >      void foo(int k);
    > >   };

    >
    > >   template<int N>
    > >   void S::foo(int k) {}

    >
    > >   template<>
    > >   void S::foo<0>(int k) {}

    >
    > > Cheers!
    > > SG

    >
    > Is this also possible for the template function in the template class ?


    You mean "function template" and "class template". The answer is
    yes. It's something along the lines of

    template<typename T>
    template<int N>
    void S<T>::foo(int k) {}

    template<typename T>
    template<>
    void S<T>::foo<0>(int k) {}


    Cheers!
    SG
     
    SG, Apr 1, 2009
    #5
  6. Guest

    I tried what suggested in SG's mail, but did not work.

    I think specialization of method is not allowed.

    Anyway, since the class had not that many members, I changed my design
    putting the second template argument in the outer class. Then it
    became easy to specialise it.
     
    , Apr 1, 2009
    #6
  7. ZikO Guest

    SG wrote:
    > You mean "function template" and "class template".

    Yes. I meant that.

    > yes. It's something along the lines of
    >
    > template<typename T>
    > template<int N>
    > void S<T>::foo(int k) {}
    >
    > template<typename T>
    > template<>
    > void S<T>::foo<0>(int k) {}


    I have tried something as below:

    //------------------------------------
    #include <iostream>
    template<class T> class A {
    public:
    template<size_t N> void f();
    };
    template<class T> template<size_t N> void A<T>::f() {
    std::cout << N << std::endl;
    }
    template<class T> template<> void A<T>::f<0>() {
    std::cout << "Stopping ..." << std::endl;
    }
    int main() {
    A<int> a;
    a.f<10>();
    a.f<0>();
    }
    //------------------------------------

    test2.cpp:10: error: invalid explicit specialization before '>' token
    test2.cpp:10: error: enclosing class templates are not explicitly
    specialized
    test2.cpp:10: error: template-id 'f<0>' for 'void A<T>::f()' does not
    match any template declaration


    Well, as I found there was no matching f<0> to anything, I added
    declaration in the class template, so appart from the class definition,
    everything looks the same in the code:

    //-------------------------------------
    #include <iostream>
    template<class T> class A {
    public:
    template<size_t N> void f();
    template<> void f<0>();
    };
    template<class T> template<size_t N> void A<T>::f() {
    std::cout << N << std::endl;
    }
    template<class T> template<> void A<T>::f<0>() {
    std::cout << "Stopping ..." << std::endl;
    }
    int main() {
    A<int> a;
    a.f<10>();
    a.f<0>();
    }
    //-------------------------------------

    but it looks even worse:
    test2.cpp:6: error: explicit specialization in non-namespace scope
    'class A<T>'
    test2.cpp:11: error: invalid explicit specialization before '>' token
    test2.cpp:11: error: enclosing class templates are not explicitly
    specialized
    test2.cpp:11: error: template-id 'f<0>' for 'void A<T>::f()' does not
    match any template declaration

    So what do you think I am doing wrong here?


    Cheers!
    Ziko
     
    ZikO, Apr 1, 2009
    #7
  8. SG Guest

    On 1 Apr., 13:23, wrote:
    > I tried what suggested in SG's mail, but did not work.
    > I think specialization of method is not allowed.


    I haven't tested member function specialization of a class template
    and I thought it was supposed to work. Sorry for the trouble.

    As a rule of thumb you should try to avoid specializing function
    templates altogether. There are other alternatives (like overloading
    function templates or turning a function template into a non-templated
    member function of some class template).


    Cheers!
    SG
     
    SG, Apr 1, 2009
    #8
  9. Triple-DES Guest

    On 1 Apr, 12:52, SG <> wrote:
    > On 1 Apr., 12:37, ZikO <> wrote:
    >
    >
    >
    >
    >
    > > SG wrote:
    > > > Yes. Have you tried the namespace scope? :p

    >
    > > >   struct S
    > > >   {
    > > >      template<int N>
    > > >      void foo(int k);
    > > >   };

    >
    > > >   template<int N>
    > > >   void S::foo(int k) {}

    >
    > > >   template<>
    > > >   void S::foo<0>(int k) {}

    >
    > > > Cheers!
    > > > SG

    >
    > > Is this also possible for the template function in the template class ?

    >
    > You mean "function template" and "class template".  The answer is
    > yes.  It's something along the lines of
    >
    >    template<typename T>
    >    template<int N>
    >    void S<T>::foo(int k) {}
    >
    >    template<typename T>
    >    template<>
    >    void S<T>::foo<0>(int k) {}


    The second example is ill-formed. A member template can not be
    explicitly (fully) specialized unless the enclosing class template is
    also explicitly (fully) specialized.

    template<>
    template<>
    void S<int>::foo<0>(int k) {} // ok

    template<>
    template<int N>
    void S<int>::foo<0>(int k) {} // ok

    template<typename T>
    template<>
    void S<T>::foo<0>(int k) {} // ill-formed
     
    Triple-DES, Apr 1, 2009
    #9
  10. wrote:
    > The following syntax cause gcc to complain about:
    > - explicit specialization in non-namespace scope
    > - enclosing class templates are not explicitly specialized
    >
    > So I guess that I need to put the specialization of foo<0> somewhere
    > out of the class definition, but what is the correct syntax to do
    > that?
    >
    > Thanks a lot
    >
    > template <class A>
    > class MyClass
    > {
    > template <unsigned char N>
    > void foo( sie_t int ) { /* ... */ }
    >
    > template <>
    > void foo<0>( sie_t int ) { /* ... */ }
    > };
    >


    There's no immediate correct syntax for this. Explicit specialization of
    a member template without explicit specialization of enclosing template
    is not allowed in C++.

    If the inner template was a class template, you could've worked around
    this limitation by introducing a dummy parameter and using partial
    specialization instead of explicit one. So, you can try wrapping your
    'foo' into a class (as a static member) and applying this workaround

    template <class A>
    class MyClass
    {
    template <unsigned char N, unsigned char DUMMY = 0>
    struct S
    {
    static void foo( int x ) { /* ... */ }
    };

    template <unsigned char DUMMY>
    struct S<0, DUMMY>
    {
    static void foo( int x ) { /* ... */ }
    };
    };

    This looks like workaround on workaround, and is generally ugly, but it
    works.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Apr 1, 2009
    #10
  11. wrote:

    > The following syntax cause gcc to complain about:
    > - explicit specialization in non-namespace scope
    > - enclosing class templates are not explicitly specialized


    Here's another workaround:

    #include <iostream>

    template <int i>
    struct int_ { static const int value = i; };

    // or #include <boost/mpl/int.hpp>

    template <class A>
    class MyClass {
    private:
    template <int N>
    void foo(int x, int_<N>)
    {
    std::cout << N << ',';
    foo(x, int_<N-1>());
    }
    // note overload, not specialization
    void foo(int x, int_<0>)
    { std::cout << " x = " << x; }
    public:
    template <unsigned char N>
    void foo(int x) { foo(x, int_<N>()); }
    };

    int main()
    {
    MyClass<float> m;
    m.foo<3>(5);
    return 0;
    }


    Martin

    --
    Quidquid latine scriptum est, altum videtur.
     
    Martin Eisenberg, Apr 1, 2009
    #11
    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. joon
    Replies:
    1
    Views:
    520
    Roedy Green
    Jul 8, 2003
  2. Dan

    correct or not correct?

    Dan, Oct 2, 2003, in forum: HTML
    Replies:
    7
    Views:
    446
  3. Oplec
    Replies:
    1
    Views:
    360
    alex wang
    Oct 27, 2003
  4. Andy Champ
    Replies:
    0
    Views:
    266
    Andy Champ
    Mar 25, 2008
  5. J.Ram
    Replies:
    7
    Views:
    655
Loading...

Share This Page