inline template function?
Asked Answered
R

4

44

Do I need inline template functions if they are included in several cpp files? Thanks.

template<bool> inline QString GetText();
template<> inline QString GetText<true>() {return "true";}
template<> inline QString GetText<false>() {return "false";}
Runner answered 16/7, 2013 at 2:36 Comment(2)
What do you hope to get from inline template functions?Salamander
possible duplicate of Does it make any sense to use inline keyword with templates?Lawler
J
49

You do, because those are full function specializations, and therefore subject to the one-definition rule just like normal functions.

Justify answered 16/7, 2013 at 2:43 Comment(2)
For the template and not fully specialized ones, I can remove inline keyword. Is it right? Like template<bool> QString GetText();Runner
@user1899020: Yes, you can.Justify
M
28

Yes, you need the inline specifier there.

The ODR (one-definition rule) states that there must be exactly one definition of a variable, function, class, enum or template. Exceptions relevant for your question are listed in §3.2/5 (C++11) (emphasis mine):

There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. [...]

Template specializations for which all parameters are specified (i.e. explicit specializations) are not listed there, and §14.7.3/12 says:

An explicit specialization of a function template is inline only if it is declared with the inline specifier or defined as deleted, and independently of whether its function template is inline. [ Example:

template<class T> void f(T) { /∗ ... ∗/ }
template<class T> inline T g(T) { /∗ ... ∗/ }
template<> inline void f<>(int) { /∗ ... ∗/ }  // OK: inline
template<> int g<>(int) { /∗ ... ∗/ }          // OK: not inline

— end example ]

Misprision answered 16/7, 2013 at 2:57 Comment(2)
It seems template<> int g<>(int) { /∗ ... ∗/ } needs keyword inline in my testing.Runner
@Runner Have you actually read the answer? If you include it in several cpp files that are linked together, then yes, you need inline. That's what the example (which is from the Standard) says.Misprision
M
2

There is no reason for the inline keyword in a template declaration but there is a need for one in a template full specialization. (You don't need to add the inline keyword for the first line but the second and third one need it.)

Each translation unit which uses the template needs to contain the template definition, so the best way is to include it in a header file and include that header file in source files which use it.

In C++ standard n3376 for 3.2/6, there can be more than one definition of a class template for the whole application, given that the definition is the same.

===============

Updated the answer based on @JesseGood comments (need inline for template full specialization). Thanks, Jesse, for pointing that out.

Mercedezmerceer answered 16/7, 2013 at 2:42 Comment(5)
You need the inline keyword. Those are template specializations, and would violate ODR if included in multiple source files.Unconventionality
See [temp.expl.spec]/12 "An explicit specialization of a function template is inline only if it is declared with the inline specifier or defined as deleted, and independently of whether its function template is inline."Ferdinandferdinanda
@Mercedezmerceer You are referring to a draft for C++14. In the current C++11, the relevant section is 3.2/5. Also, if you had included the full quotation, you'd have noticed that explicit template specializations are not mentioned as exceptions in that section (neither in C++11 nor C++14).Misprision
@Misprision I didn't noticed that full explicit template sepcializations are not included in the expcetion list of 3.2/5. Does there any reason why standard treat full specialization and template function different? I assume there should be some reason, but i cannot figure it out.Mercedezmerceer
@Mercedezmerceer The reason is that fully (i.e. explicitly) specialized function templates are no longer templates. They are functions and behave in the same way as functions. (This is also reflected in the fact that you won't need an explicit instantiation for an explicitly specialized function template. Explicit specialization implies instantiation to a function.)Misprision
P
0

It seem that the template method must be defined in the same file which is building, You don't need to use the 'inline' keyword for they were build in each cpp file which include it.

Pavilion answered 16/7, 2013 at 2:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.