@@ -397,7 +397,20 @@ <h3 id="Inline_Functions">Inline Functions</h3>
397
397
< div class ="definition ">
398
398
< p > You can declare functions in a way that allows the compiler to expand
399
399
them 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 >
401
414
</ div >
402
415
403
416
< div class ="pros ">
@@ -436,6 +449,71 @@ <h3 id="Inline_Functions">Inline Functions</h3>
436
449
place its definition in the class, either for convenience
437
450
or to document its behavior, e.g., for accessors and
438
451
mutators.</ 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 >
439
517
</ div >
440
518
441
519
</ div >
@@ -2514,7 +2592,6 @@ <h3 id="General_Rules">General Rules</h3>
2514
2592
< li > Embrace templates/C++14 when it makes the code more correct (more clear
2515
2593
or more readable also implies more correct).</ li >
2516
2594
< li > Minimize template requirements on public interfaces.</ li >
2517
- < li > Avoid explicit template instantiations in cc files when possible.</ li >
2518
2595
</ ul >
2519
2596
2520
2597
</ div >
@@ -5552,7 +5629,7 @@ <h3 id="TODO_Comments">TODO Comments</h3>
5552
5629
< div >
5553
5630
< pre > // TODO(kl@gmail.com): Use a "*" here for concatenation operator.
5554
5631
// TODO(Zeke) change this to use relations.
5555
- // TODO(bug 12345): remove the "Last visitors" feature
5632
+ // TODO(# 12345): remove the "Last visitors" feature
5556
5633
</ pre >
5557
5634
</ div >
5558
5635
@@ -5562,6 +5639,16 @@ <h3 id="TODO_Comments">TODO Comments</h3>
5562
5639
specific event ("Remove this code when all clients can
5563
5640
handle XML responses.").</ p >
5564
5641
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 >
5565
5652
</ div >
5566
5653
5567
5654
< h3 id ="Deprecation_Comments "> Deprecation Comments</ h3 >
0 commit comments