@@ -397,7 +397,20 @@ <h3 id="Inline_Functions">Inline Functions</h3>
397397< div class ="definition ">
398398< p > You can declare functions in a way that allows the compiler to expand
399399them inline rather than calling them through the usual
400- function call mechanism.</ p >
400+ function call mechanism.
401+ < span class ="drake "> To achieve this, define the function in the header
402+ (< tt > *.h</ tt > ) file, instead of the < tt > *.cc</ tt > file.</ span >
403+ </ p >
404+
405+ < p class ="drake "> Note that
406+ < a href ="https://en.cppreference.com/w/cpp/language/class_template#Explicit_instantiation ">
407+ explicit template instantiation</ a > enables the use of templated classes or
408+ functions without defining them in the header file.</ p >
409+
410+ < p class ="drake "> The C++ keyword < tt > inline</ tt > is a separate concept
411+ related to linking, not function inlining. Some function definitions need
412+ to be marked with the < tt > inline</ tt > keyword to avoid linking errors related
413+ to multiple definitions.</ p >
401414</ div >
402415
403416< div class ="pros ">
@@ -436,6 +449,71 @@ <h3 id="Inline_Functions">Inline Functions</h3>
436449place its definition in the class, either for convenience
437450or to document its behavior, e.g., for accessors and
438451mutators.</ p >
452+
453+ < p class ="drake "> The use of a numerical scalar class template is not a
454+ sufficient reason on its own to place a method definition in a header file.
455+ When a class is templated only on its numerical scalar type, Drake provides the
456+ < a href ="https://drake.mit.edu/doxygen_cxx/group__default__scalars.html ">
457+ default scalars</ a > macros to declare and define the template instantiations
458+ that allow placing definitions into the < tt > *.cc</ tt > file. These macros should
459+ be used whenever practical, and the class's method definitions should be placed
460+ into the < tt > *.cc</ tt > file in most cases, consistent with the above rules of
461+ thumb.</ p >
462+
463+ < p class ="drake "> Example header file:</ p >
464+
465+ < pre class ="drake "> #include "drake/common/default_scalars.h"
466+
467+ namespace sample {
468+
469+ template <typename T>
470+ class MySystem final : public LeafSystem<T> {
471+ public:
472+ // Expensive functions such as this constructor or destructor are not inlined.
473+ MySystem();
474+ ~MySystem() final;
475+
476+ // Short and inexpensive accessors can be inlined.
477+ int size() { return get_output_port(0).size(); }
478+
479+ private:
480+ // This calculation function is also expensive, and therefore isn't inlined.
481+ void CalcFoo(const Context<T>& context, BasicVector<T>* output);
482+ };
483+
484+ } // namespace sample
485+
486+ DRAKE_DECLARE_CLASS_TEMPLATE_INSTANTIATIONS_ON_DEFAULT_SCALARS(
487+ class ::sample::MySystem)
488+ </ pre >
489+
490+ < p class ="drake "> Example cc file:</ p >
491+ < pre class ="drake "> #include "my_system.h"
492+
493+ namespace sample {
494+
495+ // Even though the constructor appears to be short, by virtue of implicitly
496+ // calling the LeafSystem base class constructor it fails to meet the 10-line
497+ // rule of thumb.
498+ template <typename T>
499+ MySystem<T>::MySystem() = default;
500+
501+ // Ditto for the destructor.
502+ template <typename T>
503+ MySystem<T>::~MySystem() = default;
504+
505+ template <typename T>
506+ void MySystem<T>::CalcFoo(
507+ const Context<T>& context,
508+ BasicVector<T>* output) {
509+ // ... (10+ lines long, etc.) ...
510+ }
511+
512+ } // namespace sample
513+
514+ DRAKE_DEFINE_CLASS_TEMPLATE_INSTANTIATIONS_ON_DEFAULT_SCALARS(
515+ class ::sample::MySystem)
516+ </ pre >
439517</ div >
440518
441519</ div >
@@ -2514,7 +2592,6 @@ <h3 id="General_Rules">General Rules</h3>
25142592 < li > Embrace templates/C++14 when it makes the code more correct (more clear
25152593 or more readable also implies more correct).</ li >
25162594 < li > Minimize template requirements on public interfaces.</ li >
2517- < li > Avoid explicit template instantiations in cc files when possible.</ li >
25182595</ ul >
25192596
25202597</ div >
@@ -5552,7 +5629,7 @@ <h3 id="TODO_Comments">TODO Comments</h3>
55525629< div >
55535630< pre > // TODO(
[email protected] ): Use a "*" here for concatenation operator.
55545631// TODO(Zeke) change this to use relations.
5555- // TODO(bug 12345): remove the "Last visitors" feature
5632+ // TODO(# 12345): remove the "Last visitors" feature
55565633</ pre >
55575634</ div >
55585635
@@ -5562,6 +5639,16 @@ <h3 id="TODO_Comments">TODO Comments</h3>
55625639specific event ("Remove this code when all clients can
55635640handle XML responses.").</ p >
55645641
5642+ < p class ="drake "> For multi-line TODO comments, we allow a specific indentation
5643+ convention that is compatible with the CLion IDE's syntax highlighting:</ p >
5644+
5645+ < pre class ="drake "> // TODO(#12345): This is a multi-line comment where after each line break we
5646+ // use one or more extra horizontal spaces so that the subsequent lines are
5647+ // understood by CLion to be a continuation of the first line.
5648+ </ pre >
5649+
5650+ < p class ="drake "> This indentation is allowed, but not required. We mention it
5651+ here only for the avoidence of doubt during code reviews.</ p >
55655652</ div >
55665653
55675654< h3 id ="Deprecation_Comments "> Deprecation Comments</ h3 >
0 commit comments