Skip to content

Commit a29bc47

Browse files
authored
Merge pull request #33 from jwnimmer-tri/clarifications-2020-08
Add some recent clarifications
2 parents 32019d0 + b6a80e5 commit a29bc47

File tree

1 file changed

+90
-3
lines changed

1 file changed

+90
-3
lines changed

cppguide.html

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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
399399
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>
401414
</div>
402415

403416
<div class="pros">
@@ -436,6 +449,71 @@ <h3 id="Inline_Functions">Inline Functions</h3>
436449
place its definition in the class, either for convenience
437450
or to document its behavior, e.g., for accessors and
438451
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 &lt;typename T&gt;
470+
class MySystem final : public LeafSystem&lt;T&gt; {
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&lt;T&gt;& context, BasicVector&lt;T&gt;* 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 &lt;typename T&gt;
499+
MySystem&lt;T&gt;::MySystem() = default;
500+
501+
// Ditto for the destructor.
502+
template &lt;typename T&gt;
503+
MySystem&lt;T&gt;::~MySystem() = default;
504+
505+
template &lt;typename T&gt;
506+
void MySystem&lt;T&gt;::CalcFoo(
507+
const Context&lt;T&gt;& context,
508+
BasicVector&lt;T&gt;* 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(kl@gmail.com): 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>
55625639
specific event ("Remove this code when all clients can
55635640
handle 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

Comments
 (0)