| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 
 | .. title:: clang-tidy - modernize-pass-by-value
modernize-pass-by-value
=======================
With move semantics added to the language and the standard library updated with
move constructors added for many types it is now interesting to take an
argument directly by value, instead of by const-reference, and then copy. This
check allows the compiler to take care of choosing the best way to construct
the copy.
The transformation is usually beneficial when the calling code passes an
*rvalue* and assumes the move construction is a cheap operation. This short
example illustrates how the construction of the value happens:
.. code-block:: c++
    void foo(std::string s);
    std::string get_str();
    void f(const std::string &str) {
      foo(str);       // lvalue  -> copy construction
      foo(get_str()); // prvalue -> move construction
    }
.. note::
   Currently, only constructors are transformed to make use of pass-by-value.
   Contributions that handle other situations are welcome!
Pass-by-value in constructors
-----------------------------
Replaces the uses of const-references constructor parameters that are copied
into class fields. The parameter is then moved with `std::move()`.
Since ``std::move()`` is a library function declared in `<utility>` it may be
necessary to add this include. The check will add the include directive when
necessary.
.. code-block:: c++
     #include <string>
     class Foo {
     public:
    -  Foo(const std::string &Copied, const std::string &ReadOnly)
    -    : Copied(Copied), ReadOnly(ReadOnly)
    +  Foo(std::string Copied, const std::string &ReadOnly)
    +    : Copied(std::move(Copied)), ReadOnly(ReadOnly)
       {}
     private:
       std::string Copied;
       const std::string &ReadOnly;
     };
     std::string get_cwd();
     void f(const std::string &Path) {
       // The parameter corresponding to 'get_cwd()' is move-constructed. By
       // using pass-by-value in the Foo constructor we managed to avoid a
       // copy-construction.
       Foo foo(get_cwd(), Path);
     }
If the parameter is used more than once no transformation is performed since
moved objects have an undefined state. It means the following code will be left
untouched:
.. code-block:: c++
  #include <string>
  void pass(const std::string &S);
  struct Foo {
    Foo(const std::string &S) : Str(S) {
      pass(S);
    }
    std::string Str;
  };
Known limitations
^^^^^^^^^^^^^^^^^
A situation where the generated code can be wrong is when the object referenced
is modified before the assignment in the init-list through a "hidden" reference.
Example:
.. code-block:: c++
   std::string s("foo");
   struct Base {
     Base() {
       s = "bar";
     }
   };
   struct Derived : Base {
  -  Derived(const std::string &S) : Field(S)
  +  Derived(std::string S) : Field(std::move(S))
     { }
     std::string Field;
   };
   void f() {
  -  Derived d(s); // d.Field holds "bar"
  +  Derived d(s); // d.Field holds "foo"
   }
Note about delayed template parsing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When delayed template parsing is enabled, constructors part of templated
contexts; templated constructors, constructors in class templates, constructors
of inner classes of template classes, etc., are not transformed. Delayed
template parsing is enabled by default on Windows as a Microsoft extension:
`Clang Compiler User's Manual - Microsoft extensions`_.
Delayed template parsing can be enabled using the `-fdelayed-template-parsing`
flag and disabled using `-fno-delayed-template-parsing`.
Example:
.. code-block:: c++
   template <typename T> class C {
     std::string S;
   public:
 =  // using -fdelayed-template-parsing (default on Windows)
 =  C(const std::string &S) : S(S) {}
 +  // using -fno-delayed-template-parsing (default on non-Windows systems)
 +  C(std::string S) : S(std::move(S)) {}
   };
.. _Clang Compiler User's Manual - Microsoft extensions: https://clang.llvm.org/docs/UsersManual.html#microsoft-extensions
.. seealso::
  For more information about the pass-by-value idiom, read: `Want Speed? Pass by Value`_.
  .. _Want Speed? Pass by Value: https://web.archive.org/web/20140205194657/http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Options
-------
.. option:: IncludeStyle
   A string specifying which include-style is used, `llvm` or `google`. Default
   is `llvm`.
.. option:: ValuesOnly
   When `true`, the check only warns about copied parameters that are already
   passed by value. Default is `false`.
 |