CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Sep 2015
    Posts
    3

    [RESOLVED] ambiguous behaviour of a class template with specialised function

    I have got the following code in my header file:
    Code:
    template <class TType>
    class CTestTmpl
    {
    public:
               CTestTmpl() {};
              ~CTestTmpl() {};
       void    Get() const;
    private:
    };
    
    template <class TType>
    void
    CTestTmpl<TType>::Get() const
    {
          std::cout << "This is not specialized: " << std::endl;
    }
    Then, I have the following specialised function:
    Code:
        template <>
        void
        CTestTmpl<int>::Get() const
        {
              std::cout << "This is a specialized implementation: " << std::endl;
        }
    If I put this specialised function in a ".cc" file, and then call it from some main function, like this:
    Code:
        int main()
        {
              CTestTmpl<int> intTmpl;   
              intTmpl.Get();
              CTestTmpl<float> floatTmpl;   
              floatTmpl.Get();
        }
    it works as expected: The "intTmpl" uses the specialised function, and the "floatTmpl" uses the general function implementation. (The output is respectively: "This is a specialized implementation: " and "This is not specialized: ".)
    However, if I put the CTestTmpl.o file in a lib, link to it from a different program, and execute the same code, both "intTmpl" and "floatTmpl" use the general function implementation. (The output is for both: "This is not specialized: ".)

    On the other hand, if I put the specialised function in the header file, it will not compile in the "local code" (it complains the function is defined twice), but, when I compile only the class and put it in a lib, and link to it from the different program, now "intTmpl" correctly uses the specialised implementation and "floatTmpl" the general implementation. (With output respectively: "This is a specialized implementation: " and "This is not specialized: ".)

    Could anybody explain to me what's going on here, please?
    Where should I put the specialised function?
    And, once I have specialised a function for one type (integer), do I have to specialise it for all types (float, double, ...)?

    Best regards,

    Machiel

  2. #2
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: ambiguous behaviour of a class template with specialised function

    Quote Originally Posted by machielk View Post
    I have got the following code in my header file:
    Code:
    template <class TType>
    class CTestTmpl
    {
    public:
               CTestTmpl() {};
              ~CTestTmpl() {};
       void    Get() const;
    private:
    };
    
    template <class TType>
    void
    CTestTmpl<TType>::Get() const
    {
          std::cout << "This is not specialized: " << std::endl;
    }
    Then, I have the following specialised function:
    Code:
        template <>
        void
        CTestTmpl<int>::Get() const
        {
              std::cout << "This is a specialized implementation: " << std::endl;
        }
    If I put this specialised function in a ".cc" file, and then call it from some main function, like this:
    Code:
        int main()
        {
              CTestTmpl<int> intTmpl;   
              intTmpl.Get();
              CTestTmpl<float> floatTmpl;   
              floatTmpl.Get();
        }
    it works as expected: The "intTmpl" uses the specialised function, and the "floatTmpl" uses the general function implementation. (The output is respectively: "This is a specialized implementation: " and "This is not specialized: ".)
    However, if I put the CTestTmpl.o file in a lib, link to it from a different program, and execute the same code, both "intTmpl" and "floatTmpl" use the general function implementation. (The output is for both: "This is not specialized: ".)

    On the other hand, if I put the specialised function in the header file, it will not compile in the "local code" (it complains the function is defined twice), but, when I compile only the class and put it in a lib, and link to it from the different program, now "intTmpl" correctly uses the specialised implementation and "floatTmpl" the general implementation. (With output respectively: "This is a specialized implementation: " and "This is not specialized: ".)

    Could anybody explain to me what's going on here, please?
    Where should I put the specialised function?
    And, once I have specialised a function for one type (integer), do I have to specialise it for all types (float, double, ...)?

    Best regards,

    Machiel
    It sounds like you need to just forward declare your specialized implementation:

    Code:
    template <>
    void
    CTestTmpl<int>::Get() const;
    Your compiler needs to *know* it exists to load it from lib (else it will just use its own default definition).

    Regarding the "it complains the function is defined twice": It sounds like you might simply be missing include guards? If it complains about duplicate definition, this is a *compile* error: It happens before the linker, so at this point, there is no lib to care about. Only code.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  3. #3
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: ambiguous behaviour of a class template with specialised function

    if you want a library (or a dll) to have a specific specialisation of a template availble to link to, then you need to explicitely instantiate the specialization. and make sure this instantiation is linkable.

  4. #4
    Join Date
    Sep 2015
    Posts
    3

    Re: ambiguous behaviour of a class template with specialised function

    Hi monarch_dodra and OReubens,

    You are both right! I just implemented it the way you said and now it works perfectly.
    Many thanks for your help!

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: ambiguous behaviour of a class template with specialised function

    Quote Originally Posted by OReubens View Post
    and make sure this instantiation is linkable.
    ... and make sure that all its members can be instantiated as well ( for OP information, often templates are *not* designed to have all their members instantiated for a given type ... )

    Quote Originally Posted by machielk View Post
    You are both right! I just implemented it the way you said and now it works perfectly.
    ok and all right, but for the future, keep in mind that the behaviour you observed in your OP is not guaranteed; IOW, whenever two translation units "see" different specializations of a template the result is generally undefined and no diagnostic is often required. So, the fact that something "works" does not mean it won't explode in the future ...

  6. #6
    Join Date
    Sep 2015
    Posts
    3

    Re: [RESOLVED] ambiguous behaviour of a class template with specialised function

    @superbonzo

    Sorry, you lost me a bit there.
    First of, what do you mean with "OP"?

    What I do right now is the following:
    In my header file I define my class template with all its member functions.
    In the same header file, I give the implementation of all non-specialised methods plus (following monach and OReubens) the explicit instantiation of some specialised methods.
    In the source file, I give the implementation of the same specialised methods.

    With this, all member functions (specialised or not) should work correctly, right?

  7. #7
    Join Date
    May 2007
    Posts
    811

    Re: [RESOLVED] ambiguous behaviour of a class template with specialised function

    Quote Originally Posted by machielk View Post
    @superbonzo

    Sorry, you lost me a bit there.
    First of, what do you mean with "OP"?
    Original Post

  8. #8
    Join Date
    Oct 2008
    Posts
    1,456

    Re: [RESOLVED] ambiguous behaviour of a class template with specialised function

    Quote Originally Posted by machielk View Post
    With this, all member functions (specialised or not) should work correctly, right?
    yes, it's right.

    I just wanted to warn you that given the code in your Original Post ( thank you STLDude ! ) :

    Code:
    // a.hpp
    
    template <class T> struct A { void foo() { do_something(); } };
    
    // b.cpp
    #include <a.hpp>
    
    int main( A<int> a; a.foo(); };
    
    // c.cpp
    #include <a.hpp>
    
    template <>
    void A<int>::foo() { do_something_else(); } };
    the result is undefined and the compiler is not required to warn you in any way. That is, it may work as expected or not, it may give a compiler/linker error or not.

    The moral of the story is that every cpp file must "see" the "same"(*) template definitions, or you 'll get in a lot of troubles, indipendently on whether the result appears to work or not.

    ((*) anyway, for your info, this does not mean that the include chain must be *exactly* the same ... but that's another story )

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured