1

I am a little confused when one should inline specializations. From this question it gets clear that every specialization must be inlined to avoid duplicate symbol errors. But what if I want to have a declaration of the specialization first, how would that change things?

If we consider this example:

template<typename T>
class myClass
{
public:
    static void myPrint(T myVal);
}

#include "declarations.hpp"

//-----------------------------------------------

//declarations.hpp

template<typename T>
void myClass<T>::myPrint(T myVal) 
{
    cout << "printing unknown type " << myVal;
}

template <>
void myClass<int>::myPrint(int myVal); //inline here or in definition?

template <>
void myClass<float>::myPrint(float myVal); //inline here or in definition?

//-----------------------------------------------

//some_file_that_includes_myClass_header.cpp

template <>
void myClass<int>::myPrint(int myVal) //inline or no inline?
{
    cout << "printing int " << myVal;
}

//-----------------------------------------------

//some_other_file_that_includes_myClass_header.cpp

template <>
void myClass<float>::myPrint(float myVal) //inline or no inline?
{
    cout << "printing float " << myVal;
}

What would be the correct way to do this, and why?

Gregor Sattel
  • 352
  • 3
  • 12

2 Answers2

2

Like the other Q&A mentions, the specialization is its own entity. If you do as you did, declare the specialization in a header, and then define them in another (single) TU, that is well-formed. Any TU that includes that header will see that the specialization for int and float are only declarations. As such, their definition may be placed elsewhere, just like a non-template function.

If you want a header only library, where the specialized functions are defined inline, then you must use the inline specifier, as the ODR requires.

Neither way is "the correct" way in the sense you seem to be asking about. Each has its own advantages and disadvantages. Defining the functions inline helps make libraries be header only. But if the functions are complex, then all of their dependencies are pulled into every TU that includes the header. Also, changing the specializations will cause all of those TU's to be re-compiled. So there's merit for tucking the implementation away too at times. You'll need to judge on a case by case basis.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • So in this case inline is only important if I have definitions inside the header, thus meaning that inline is not necessary in the case I've described in the question? – Gregor Sattel Sep 13 '20 at 07:58
  • 1
    @GregorSattel - It's not needed in the case you described. `inline` is primarily a linkage specifier. It's needed when multiple definitions of a function may end up appearing in a program (such as a function defined in a header). It tells the compiler/linker that you promise all those definitions are in fact identical, so any one may be picked as "the definition". If you instead declare/define the function, then there already is only one definition, and so no point in adding the inline specifier. – StoryTeller - Unslander Monica Sep 13 '20 at 08:02
-1

What would be the correct way to do this, and why?

These specializations need to be inlined either, and for the same reason as with the templated versions.

If these aren't inlined you'll end up with multiple definitions of these symbols across any compilation units, which include that header.

For example

template <>
inline void myClass<int>::myPrint(int myVal) {
    cout << "printing int " << myVal;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • And where should I put the inline keyword in this case? Declaration, definition or both? – Gregor Sattel Sep 13 '20 at 06:26
  • You need to put it at the definitoin before the return type of the functions. – πάντα ῥεῖ Sep 13 '20 at 06:27
  • 1
    How would putting the inline specifier on a method in a source file help? Doesn't the compiler need to be able to see the definition? This will only define the method for some_other_file_that_includes_myClass_header.cpp. – theWiseBro Sep 13 '20 at 06:50