Rule A12-1-2 (required, implementation, automated)

Both NSDMI and a non-static member initializer in a constructor shall not be used in the same type.

Rationale

Since 2011 C++ Language Standard it is allowed to initialize a non-static member along with the declaration of the member in the class body using NSDMI (“non-static data member initializer”). To avoid possible confusion which values are actually used,

if any member is initialized by NSDMI or with a constructor, then all others should be initialized the same way.

Exception

The move and copy constructors are exempt from this rule, because these constructors copy the existing values from other objects.

Example

// $Id: A12-1-2.cpp 271696 2017-03-23 09:23:09Z piotr.tanski $
#include <cstdint>
#include <utility>
class A
{
public:
A() : i1{0}, i2{0} // Compliant - i1 and i2 are initialized by the
// constructor only. Not compliant with A12-1-3
{
}
// Implementation

private:
std::int32_t i1;
std::int32_t i2;
};
class B
{
public:
// Implementation

private:
std::int32_t i1{0};
std::int32_t i2{
0}; // Compliant - both i1 and i2 are initialized by NSDMI only
};
class C
{
public:
C() : i2{0} // Non-compliant - i1 is initialized by NSDMI, i2 is in
// member in member initializer list
{
}
C(C const& oth) : i1{oth.i1}, i2{oth.i2} // Compliant by exception
{
}
C(C&& oth)
: i1{std::move(oth.i1)},
i2{std::move(oth.i2)} // Compliant by exception
{
}
// Implementation

private:
std::int32_t i1{0};
std::int32_t i2;

};

See also

HIC++ v4.0 [9]:12.4.3 Do not specify both an NSDMI and a member initializer in a constructor for the same non static member