7
votes

Are methods of templated classes implied inline linkage (not talking about the inline optimization), or is it just templated methods which are?

// A.h

template<typename T>
class A
{
public:
    void func1();                       //  #1
    virtual void func2();               //  #2
    template<typename T2> void func3(); //  #3
};

template<typename T>
void A<T>::func1(){}    //  #1

template<typename T>
void A<T>::func2(){}    //  #2

template<typename T>
template<typename T2>
void A<T>::func3<T2>(){}    //  #3

Are all the above cases inline [linkage]? (Should I explicitly write inline for any of them)?

1
You should write inline for all of them if they are all in the header file. - jxh
@user315052 Why? I argue that you should mark none of them inline, and let the compiler (who is smarter than you) make the decision to inline or not. - Jonathon Reinhart
@JonathonReinhart This concerns inline linkage, not the copy-paste kind of inline - David
@ildjarn: I am quite sure that template functions and template class member functions are special to this respect, and the quick test I came up with seems to indicate that. I don't yet have a quote from the standard. - David Rodríguez - dribeas
@Dave: That is not linkage, just whether it is inline or not. Linkage affects whether the symbols are exported in the translation unit or not, and inline functions (potentially, that is if it is not static and the function is generated out-of-line in the translation unit) are exported. Try taking the address of an inline function in two translation units (this will force an out-of-line definition, in case your compiler does not do that by default), then check what symbols are exported in the binary file and you will see that inline function. - David Rodríguez - dribeas

1 Answers

14
votes

Template functions and member functions of template classes are implicitly inline1 if they are implicitly instantiated, but beware template specializations are not.

template <typename T>
struct test {
    void f();
}
template <typename T>
void test<T>::f() {}           // inline

template <>
void test<int>::f() {}           // not inline

By lack of a better quote:

A non-exported template must be defined in every translation unit in which it is implicitly instantiated (14.7.1), unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required


1 Only in the sense that multiple definitions are allowed for them, but not for optimization purpopses. You can manually mark them inline as a hint for the optimizer.

See [basic.def.odr]/13.4 - the templates by themselves are excempt from ODR, not because they're implicitly inline.