Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inlining Template Specialization

If I have a header foo.h which I include all over my project, it seems to work fine when all it contains is:

template<typename T>
void foo(const T param) {
    cout << param << endl;
}

But I get one definition rule (ODR) errors when I add a specalization to foo.h:

template<>
void foo(const bool param) {
    cout << param << endl;
}

Obviously I can solve this by inline'ing the specialization. My question is, why do I need to? If the template doesn't violate ODR, why does a specialization?

like image 259
Jonathan Mee Avatar asked Aug 23 '18 13:08

Jonathan Mee


People also ask

What is function template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

What is explicit template specialization?

Explicit (full) specializationAllows customizing the template code for a given set of template arguments.

What is meant by template specialization Mcq?

Explanation: Template specialization is used when a different and specific implementation is to be used for a specific data type. In this program, We are using integer and character.

Can template function be inlined?

Multiple template definitions with the same name can appear in the file, but the compiler will use only the first definition. Since the template code will be inlined directly, without a call, into the code generated by the compiler, there is no need for a return instruction.


1 Answers

An explicit specialization is not implicitly inline. It must be explicitly made inline.

[temp.expl.spec]/12

An explicit specialization of a function or variable template is inline only if it is declared with the inline specifier or defined as deleted, and independently of whether its function or variable 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 ]

So you have to do it, because the standard says you have to do it.

like image 97
StoryTeller - Unslander Monica Avatar answered Nov 15 '22 00:11

StoryTeller - Unslander Monica