2

This code will be placed in a header file:

template<typename TTT>
inline Permutation<TTT> operator * (const Cycle<TTT>& cy, const Permutation<TTT>& p)
{
    return Permutation<TTT>(cy)*p;
}

Is inline necessary to avoid a linker error?

If this function is not a template and the header file is used in more than one .cpp file, inline is necessary to avoid a liker error complaining about multiple definitions for a function. It seems linker ignores this for templates.

Minimus Heximus
  • 2,683
  • 3
  • 25
  • 50
  • Do you know include guards (ifdef-define or pragma once)? Don´t make strange workarounds – deviantfan Apr 18 '14 at 08:56
  • I'm talking about a linker error. So the codes are compiled but not linked. – Minimus Heximus Apr 18 '14 at 08:58
  • I know. But, leaving "template or not" aside, your problem is a usual beginner error. Doesn´t matter if template or not. That´s why i´m asking, if i should explain this or something more difficult. – deviantfan Apr 18 '14 at 09:00
  • 1
    Yes templates are special and have to be visible to get instantiated. You can omit the inline if you don't want it. –  Apr 18 '14 at 09:00
  • @deviantfan No, this is completely unrelated to include guards. – juanchopanza Apr 18 '14 at 09:09
  • @juanchopanza: Well, i could´ve misunderstood a "what does the standard say and why" etc. as "why my code a won´t link, only part b" – deviantfan Apr 18 '14 at 09:10

3 Answers3

5

Is inline necessary to avoid a linker error?

On a function template, no. Templates, like inline functions, are subject to a more relaxed One Definition Rule which allows multiple definitions - as long as the definitions are identical and in separate translation units.

As you say, inline would be necessary if you wanted to define a non-template function in a header; non-inline functions are subject to a more strict One Definition Rule, and can only have one definition in a program.

For the gory details, this is specified by C++11 3.2/5:

There can be more than one definition of a class type, inline function with external linkage, class template, non-static function template, static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.

(The "following requirements" basically say that the definitions must be identical).

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

Consider that a template function (or function template if you prefer) is not a function at all. It is rather a recipe to create a function. The actual function is only created when and where the template is instantiated. So you do not need the inline keyword here, because template functions will not result in multiple-definition linker errors because they are not actually defined (from the linker's perspective) until they are used.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
1

Expanding on Mike Seymour's answer -- the paragraph (3.2/5) he cites in in the Standard refers to a concept called "vague linkage". Basically, it's a way of saying "we need this to exist somewhere in the resulting binary, but we don't have a clear-cut home for it in any specific object file we're emitting." On modern platforms (Windows, ELF systems such as Linux, and OS X), this is implemented using a mechanism known as COMDAT support that allows the compiler to simply generate the instantiations and other vague linkage items (vtables, typeinfos, and inline function bodies) as-needed -- the linker then is free to throw out the duplicates:

When used with GNU ld version 2.8 or later on an ELF system such as GNU/Linux or Solaris > 2, or on Microsoft Windows, duplicate copies of these constructs will be discarded at link time. This is known as COMDAT support.

This is discussed in more detail in the GCC manual (quote snipped as the Cfront model is irrelevant for modern compilers):

C++ templates are the first language feature to require more intelligence from the environment than one usually finds on a UNIX system. Somehow the compiler and linker have to make sure that each template instance occurs exactly once in the executable if it is needed, and not at all otherwise. There are two basic approaches to this problem, which are referred to as the Borland model and the Cfront model.

Borland model

Borland C++ solved the template instantiation problem by adding the code equivalent of common blocks to their linker; the compiler emits template instances in each translation unit that uses them, and the linker collapses them together. The advantage of this model is that the linker only has to consider the object files themselves; there is no external complexity to worry about. This disadvantage is that compilation time is increased because the template code is being compiled repeatedly. Code written for this model tends to include definitions of all templates in the header file, since they must be seen to be instantiated.

LThode
  • 1,843
  • 1
  • 17
  • 28