16

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)?

David
  • 27,652
  • 18
  • 89
  • 138
  • You should write `inline` for all of them if they are all in the header file. – jxh Jul 17 '12 at 17:12
  • @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 Jul 17 '12 at 17:13
  • @JonathonReinhart This concerns inline linkage, not the copy-paste kind of inline – David Jul 17 '12 at 17:14
  • 2
    @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 Jul 17 '12 at 17:18
  • @David : I think you're right. – ildjarn Jul 17 '12 at 17:19
  • 1
    `inline` is not a linkage and `inline` doesn't alter the linkage of a function. What aspect of `inline` are you actually concerned about? – CB Bailey Jul 17 '12 at 17:38
  • @CharlesBailey "`inline` doesn't alter the linkage of a function" - I beg to differ (unless you are arguing semantics, which I'm not sure about myself, so feel free to correct me) – David Jul 17 '12 at 17:42
  • 1
    @Dave: That is a two way question, *why do you think that `inline` modifies linkage?* A function can be `inline` and have internal linkage (if it is also `static`) or external linkage (otherwise). – David Rodríguez - dribeas Jul 17 '12 at 17:46
  • What's the name of what I'm talking about here? ...the name of the aspect of `inline` that lets you break ODR? I've been calling it "inline linkage" because I've heard it called that, but I don't know what's 'correct' – David Jul 17 '12 at 17:49
  • You could differ but that wouldn't make you right. ;) See (for example) here: http://stackoverflow.com/a/3540941/19563 . A local static variable in an inline function must be unique across translation units. – CB Bailey Jul 17 '12 at 17:52
  • 1
    @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 Jul 18 '12 at 03:37

1 Answers1

18

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.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • Yes, but "Are methods of templated classes implied inline, or is it just templated methods which are?" I didn't know that about specializations though, good to know! – David Jul 17 '12 at 17:19
  • David, can you please give me the reference where it says template functions are implicitly inline *but specialization are not*? I would like to know it in detail. – Nawaz Jul 17 '12 at 17:22
  • @Dave: Yes, they are also `inline`, at least for the purpose of ODR violations. – David Rodríguez - dribeas Jul 17 '12 at 17:25
  • 1
    @DavidRodríguez-dribeas: The quote doesn't say that templates *are implicitly inline **if** they are implicitly instantiated*. – Nawaz Jul 17 '12 at 17:42
  • 1
    @Nawaz: `inline` means that it is not a violation of the ODR rule if it is defined in multiple translation units within a program. The quote states that you are *required* to provide the definition in multiple translation units (as many as *odr-use* it) within a program. The requirement to provide multiple definitions within the program seems to be a good hint that it is not an ODR violation to do so, and that is effectively the same as `inline` – David Rodríguez - dribeas Jul 17 '12 at 17:48
  • 1
    @Nawaz: You can also prove it by assuming the opposite. Assuming that they are not `inline`, it means that multiple definitions will be a violation of the ODR, and that in turn means that the quote above forces you to violate the ODR, since it requires multiple definitions. Assuming that the standard does not mandate violating the standard, the premise must be incorrect. – David Rodríguez - dribeas Jul 17 '12 at 17:51
  • @DavidRodríguez-dribeas: I don't think I understand it properly. ODR means there will be one definition per TU, right? And `inline` means the function call is replaced by its definition at the call site? If so, then what ODR has to do with inline here, or how ODR implies `inline`? – Nawaz Jul 17 '12 at 17:52
  • 1
    @Nawaz: The ODR rules says that for every non-inline function there must be a single definition in the whole program, not per TU. The `inline` keyword *hints* the compiler that you want to perform the substitution, but the important part is that the definition of the function must be present in *all* TUs that use it without violating the ODR. While compilers can ignore the *hint* and produce an out-of-line definition (most compilers will produce the out of line definition even if they do inline), this is not an ODR violation. – David Rodríguez - dribeas Jul 17 '12 at 17:56
  • @DavidRodríguez-dribeas: Ohh.. I just got confused with the ODR thingy. I think I understand it now completely. Thanks. +1 – Nawaz Jul 17 '12 at 17:58
  • I read it again now, with a fresh mind. I *completely* understand it. Thanks for all the explanation. :-) – Nawaz Jul 20 '12 at 13:26
  • Using the word “inline” for this (let alone the keyword `inline`) seems to cause a lot of confusion for very little benefit. If you want to say “can be defined in multiple translation units”, just say that (or maybe “redefinable”, given sufficient context). – Davis Herring Jul 21 '23 at 14:39