2

Problems with class template member specialization.

I have a simple class and I want specialize a single member function. I'm doing like this:

template <class T>
class Object
{
public:
    Object() {}

    void print() const
    {
        std::cout << "It's the template" << std::endl;
    }
    // ...
};

template<>
void Object<int>::print() const
{
    std::cout << "It's an int" << std::endl;
}

which ends up in a compile error for multiple definition of the member function.

If just one source file includes the header everything is fine.

If two files include the header I get the following error:

/home/marc/QtProjects/QtAsp-Service/build-aspservice-Desktop_Qt_5_15_0_GCC_64bit-Debug/../src/Asp/aspobject.h:34: Fehler: multiple definition of `Asp2::print()'; main.o:/home/marc/QtProjects/QtAsp-Service/build-aspservice-Desktop_Qt_5_15_0_GCC_64bit-Debug/../src/Asp/aspobject.h:34: first defined here

This this possible in general? If yes, what is wrong.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
marca
  • 19
  • 2
  • 3
    Please edit your question and add the exact error message from your compiler. – Fantastic Mr Fox Nov 14 '20 at 00:21
  • 1
    Unfortunately it is not currently possible to specialize just a member function of a template class; you need to specialize the entire class. See [here](https://stackoverflow.com/questions/5512910/explicit-specialization-of-template-class-member-function) for a discussion of the issue. – Nathan Pierson Nov 14 '20 at 00:24
  • 1
    You have a typo in your specialization, should `AspObject`, just be `Object`? Is [this](https://ideone.com/Qbq0CI) the behaviour your are looking for? – Fantastic Mr Fox Nov 14 '20 at 00:28
  • 1
    @NathanPierson I think it is possible, the function in question is not a template function, so this questions is not quite the same. You can definitely specialize specific member functions of templated classes. – Fantastic Mr Fox Nov 14 '20 at 00:31
  • Oh, interesting! Thanks for the correction, @FantasticMrFox – Nathan Pierson Nov 14 '20 at 00:34
  • @NathanPierson It is possible in more modern C++ implementations. See below – GreatAndPowerfulOz Nov 14 '20 at 00:37
  • I don't think it's a modernity issue, it's that I didn't realize that the rule was only for templated member functions of templated classes, not all member functions of templated classes. – Nathan Pierson Nov 14 '20 at 00:40
  • Should we just close this as a typo or is there something we don't see? – drescherjm Nov 14 '20 at 00:59
  • @ Fantastic Mr Fox: You are right with the type, but this was not problem. The template class lives in a header file. If just one source file includes the header everything is fine. If two files include the header I get the following error: /home/marc/QtProjects/QtAsp-Service/build-aspservice-Desktop_Qt_5_15_0_GCC_64bit-Debug/../src/Asp/aspobject.h:34: Fehler: multiple definition of `Asp2::print()'; main.o:/home/marc/QtProjects/QtAsp-Service/build-aspservice-Desktop_Qt_5_15_0_GCC_64bit-Debug/../src/Asp/aspobject.h:34: first defined here – marca Nov 14 '20 at 01:13
  • @marca you should put the specialization in a .cpp file, I believe – GreatAndPowerfulOz Nov 14 '20 at 05:32

2 Answers2

3

Your way is correct, but fully specialized member is no longer template, so no longer implicitly inline.

You have to add inline if you keep definition in header, or split declaration (in header) and definition (in cpp).

template<>
inline void Object<int>::print()
{
    std::cout << "It's an int" << std::endl;
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
-1

The problem was that the template class is defined in a seperate header file. If only one source file includes the header it works. If two or more source files include the header GCC throws a multiple definition error. Is there a other way of doing it?

marca
  • 19
  • 2