Template class member function specialization

Discussion in 'C++' started by James Aguilar, Nov 9, 2006.

  1. Guys,

    When I specialize a template class member function (I.e. a member
    function of a template class) based on that class' type, bad things
    happen. Here's some code:

    ---- test_header.h
    #ifndef TEST_HEADER_H
    #define TEST_HEADER_H

    #include <iostream>

    template <typename T>
    class Test
    {
    public:
    void out();
    };

    template <>
    void
    Test<char>::eek:ut()
    {
    std::cout << "I am a char!\n";
    }

    template <typename T>
    void
    Test<T>::eek:ut()
    {
    std::cout << "I am a T!\n";
    }

    #endif
    ----
    ---- test_main.cpp
    #include "test_header.h"

    int main()
    {
    Test<char> t1;
    Test<int> t2;

    t1.out();
    t2.out();

    return 0;
    }
    ----
    ---- test_other.cpp
    #include "test_header.h"

    int test()
    {
    Test<char> t;
    Test<int> t2;

    t.out();
    t2.out();
    }
    ----
    ---- g++-4.1.2 reports:
    ../test_other.o: In function `Test<char>::eek:ut()':
    .../test_header.h:15: multiple definition of `Test<char>::eek:ut()'
    ../test_main.o:../test_header.h:15: first defined here
    ----

    But I thought I was supposed to put template functions and their
    specializations in the header file. It works if I inline it, but I
    don't *want* to inline it. In my real system, the function is a little
    larger.

    Any help from the gurus out there?

    Grace be with you,
    James Aguilar
     
    James Aguilar, Nov 9, 2006
    #1
    1. Advertising

  2. James Aguilar

    Guest

    James Aguilar wrote:
    > Guys,
    >
    > When I specialize a template class member function (I.e. a member
    > function of a template class) based on that class' type, bad things
    > happen. Here's some code:
    >
    > ---- test_header.h
    > #ifndef TEST_HEADER_H
    > #define TEST_HEADER_H
    >
    > #include <iostream>
    >
    > template <typename T>
    > class Test
    > {
    > public:
    > void out();
    > };
    >
    > template <>
    > void
    > Test<char>::eek:ut()
    > {
    > std::cout << "I am a char!\n";
    > }
    >
    > template <typename T>
    > void
    > Test<T>::eek:ut()
    > {
    > std::cout << "I am a T!\n";
    > }
    >
    > #endif
    > ----
    > ---- test_main.cpp
    > #include "test_header.h"
    >
    > int main()
    > {
    > Test<char> t1;
    > Test<int> t2;
    >
    > t1.out();
    > t2.out();
    >
    > return 0;
    > }
    > ----
    > ---- test_other.cpp
    > #include "test_header.h"
    >
    > int test()
    > {
    > Test<char> t;
    > Test<int> t2;
    >
    > t.out();
    > t2.out();
    > }
    > ----
    > ---- g++-4.1.2 reports:
    > ./test_other.o: In function `Test<char>::eek:ut()':
    > ../test_header.h:15: multiple definition of `Test<char>::eek:ut()'
    > ./test_main.o:../test_header.h:15: first defined here
    > ----
    >
    > But I thought I was supposed to put template functions and their
    > specializations in the header file. It works if I inline it, but I
    > don't *want* to inline it. In my real system, the function is a little
    > larger.
    >
    > Any help from the gurus out there?
    >
    > Grace be with you,
    > James Aguilar


    Your class Test is a template class. Your function out is not a
    template member function.

    So

    1>Either you first need to explicity specialize your class

    or

    2>Make your member function "out" to be a template member function and
    then specialize it.

    class Test
    {
    public:
    template <typename T>
    void out();
    };

    template<>
    void Test::Out<char>()
    {
    }
     
    , Nov 9, 2006
    #2
    1. Advertising

  3. wrote:
    >
    > Your class Test is a template class. Your function out is not a
    > template member function.
    >
    > So
    >
    > 1>Either you first need to explicity specialize your class
    >
    > or
    >
    > 2>Make your member function "out" to be a template member function and
    > then specialize it.


    I certainly can't do the second. The class I'm actually writing is an
    iterator over a specialized container. But I want the iterator's
    operator *() function to do something special, but only when it is
    templatized by char. You're saying I have to reimplement the entire
    class in order to change just one method? Or am I misreading you
    somehow?

    Yours,
    James Aguilar
     
    James Aguilar, Nov 9, 2006
    #3
  4. James Aguilar wrote:
    > Guys,
    >
    > When I specialize a template class member function (I.e. a member
    > function of a template class) based on that class' type, bad things
    > happen. Here's some code:
    >
    > ---- test_header.h
    > #ifndef TEST_HEADER_H
    > #define TEST_HEADER_H
    >
    > #include <iostream>
    >
    > template <typename T>
    > class Test
    > {
    > public:
    > void out();
    > };
    >
    > template <>


    What if you just drop this "tempalate <>" thing? What you're trying
    to do is to define the body of a particular function. It's not
    a specialisation. Of course, since you stuck it into a header you
    probably want to declare it "inline" while you're at it. Or move it
    into an implemenation file to avoid multiple definition errors.

    > void
    > Test<char>::eek:ut()
    > {
    > std::cout << "I am a char!\n";
    > }
    >
    > template <typename T>
    > void
    > Test<T>::eek:ut()
    > {
    > std::cout << "I am a T!\n";
    > }
    >
    > #endif
    > ----
    > ---- test_main.cpp
    > #include "test_header.h"
    >
    > int main()
    > {
    > Test<char> t1;
    > Test<int> t2;
    >
    > t1.out();
    > t2.out();
    >
    > return 0;
    > }
    > ----
    > ---- test_other.cpp
    > #include "test_header.h"
    >
    > int test()
    > {
    > Test<char> t;
    > Test<int> t2;
    >
    > t.out();
    > t2.out();
    > }
    > ----
    > ---- g++-4.1.2 reports:
    > ./test_other.o: In function `Test<char>::eek:ut()':
    > ../test_header.h:15: multiple definition of `Test<char>::eek:ut()'
    > ./test_main.o:../test_header.h:15: first defined here
    > ----
    >
    > But I thought I was supposed to put template functions and their
    > specializations in the header file. It works if I inline it, but I
    > don't *want* to inline it. In my real system, the function is a
    > little larger.


    So, don't inline it. Declare it in the header (without the 'template<>')
    and then define it in one of the translation units.

    >
    > Any help from the gurus out there?


    See above.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Nov 9, 2006
    #4
  5. James Aguilar

    Guest

    James Aguilar wrote:
    > wrote:
    > >
    > > Your class Test is a template class. Your function out is not a
    > > template member function.
    > >
    > > So
    > >
    > > 1>Either you first need to explicity specialize your class
    > >
    > > or
    > >
    > > 2>Make your member function "out" to be a template member function and
    > > then specialize it.

    >
    > I certainly can't do the second. The class I'm actually writing is an
    > iterator over a specialized container. But I want the iterator's
    > operator *() function to do something special, but only when it is
    > templatized by char. You're saying I have to reimplement the entire
    > class in order to change just one method? Or am I misreading you
    > somehow?


    then just take out the template <> from the top of the specialization.
    >
    > Yours,
    > James Aguilar
     
    , Nov 9, 2006
    #5
    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. Dave
    Replies:
    4
    Views:
    7,775
    pdixtl
    Jun 4, 2010
  2. Ruben Campos
    Replies:
    3
    Views:
    6,533
  3. BigMan
    Replies:
    1
    Views:
    539
  4. Joseph Turian
    Replies:
    4
    Views:
    622
    John Carson
    Mar 20, 2006
  5. toton
    Replies:
    2
    Views:
    360
    toton
    Feb 22, 2008
Loading...

Share This Page