4

It has come to my notice that C++ Standard Library defines traits by means of variable templates, which are explicitly declared as inline:

      template <class T> inline constexpr bool is_void_v = is_void<T>::value;
      template <class T> inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
      template <class T> inline constexpr bool is_integral_v = is_integral<T>::value;

I thought that all variable templates are inline by default. Is there any particular reason to declare them inline in this case?

mentalmushroom
  • 2,261
  • 1
  • 26
  • 34
  • I distinctly remember reading somewhere that at one point the standard failed to specify the linkage of non-inline template constexpr variables, so the traits were defined with `inline` to be safe. Then the defect was resolved, rendering `inline` unnecessary. – HolyBlackCat Feb 19 '21 at 21:19

2 Answers2

1

Class members which are both static and constexpr are also implicitly inline. Non-members do not have this property. And variable templates are not implicitly inline.

Indeed, non-static, non-member template functions and variables have to be explicitly declared inline.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • "And variable templates are not implicitly inline": Could you give a reference where it is stated? – mentalmushroom Feb 19 '21 at 18:52
  • 4
    @mentalmushroom: I can't give you a reference to a thing that doesn't exist. Being implicitly inline is a positive property; there's a statement in the spec that says that syntax X is implicitly inline. Not being implicitly inline is a negative property; there's nowhere that says it isn't implicitly inline because *everything* is not implicitly inline, except for the things that are. – Nicol Bolas Feb 19 '21 at 18:54
  • template functions are inline, no? We put template function definitions to header files. – Aykhan Hagverdili Feb 19 '21 at 18:54
  • @AyxanHaqverdili: "*template functions are inline, no?*" No, they're not. *Member* template functions are, but that's because they're member functions. Non-member template functions are not implicitly inline. – Nicol Bolas Feb 19 '21 at 18:55
  • @NicolBolas are free-standing function templates otherwise exempt from ODR? How come we can put them in header files if they are not inline? – Aykhan Hagverdili Feb 19 '21 at 18:59
  • @NicolBolas I see. Put it this way, could you show where it is said that member template functions (and maybe something else) are inline? – mentalmushroom Feb 19 '21 at 19:30
  • @t.niese *"As soon as you use that function template in two different compilations units with the same template arguments, the linker will complain"* Nope, it's not going to complain. Templates are exempt from ODR even when they're not inline, due to [`[basic.def.odr]/13.4`](http://eel.is/c++draft/basic.def.odr#13.4). – HolyBlackCat Feb 19 '21 at 21:26
-1

It is not true that templates are inline by default. The rules for default inlining suggest that when functions are defined within the class declaration, they should be considered for inlining. For templates, since most templates are defined inside the template class declaration, they are mostly inlined. However, it is possible to generate out-of-line templates:

template<typename T> class templateClass {
    public:
    void doSomething();
};

template<typename T> void templateClass<T>::doSomething() {
    //out of line implementation.
}
N. Prone
  • 180
  • 7
  • Do you think inline would make any difference here? According to C++ docs, the meaning of the keyword inline for functions came to mean "multiple definitions are permitted" rather than "inlining is preferred". In your example both in-class and out-of-class template definitions are already exempt to one definition rule (AFAIK). – mentalmushroom Feb 19 '21 at 19:18
  • @mentalmushroom I'm not sure, I would love an answer to this and thanks for pointing me towards that other meaning of "inline". I just know that you can "avoid implicit inlining" by doing out-of-class definitions. – N. Prone Feb 19 '21 at 19:51
  • @mentalmushroom after looking at this more, I believe ```inline``` has two meanings -- one to nudge the compiler to inline code, and another to allow for One-Definition-Rule to be bypassed, granted that the definitions are the same and have the same address. In my example, I believe compiler may complain about multiple definitions if invoked with same template parameter in different object files... – N. Prone Feb 20 '21 at 14:04
  • 1
    The point is that templates are exempt to ODR even without inline. – mentalmushroom Feb 20 '21 at 14:49
  • @mentalmushroom thank you, you taught me something brand new today. Just verified that this is completely true, at least with g++ – N. Prone Feb 20 '21 at 15:17