3

Is the following constructor considered trivial?

struct A
{
    A() : a(nullptr) {}
private:
    int* a;
};

These examples makes me a little confused. With c++11 this should also be possible:

struct A
{
private:
    int* a{nullptr};
};

and a should be properly initialized to nullptr. Here I did not define the constructor, but it should have the same form as the first implementation. Is either of these classes considered trivial?

The purpose of me asking is if I can expect move/copy constructors and assignment operators being automatically generated.

pingul
  • 3,351
  • 3
  • 25
  • 43
  • You can check by `static_assert`ing with `std::is_trivial`. – chris Jun 29 '16 at 23:10
  • 1
    Possible duplicate of [What is a non-trivial constructor in C++?](http://stackoverflow.com/questions/3899223/what-is-a-non-trivial-constructor-in-c) – Rose Kunkel Jun 29 '16 at 23:11
  • auto generation of those other functions has nothing to do with whether the constructor is trivial – M.M Jun 29 '16 at 23:11
  • I don't think I agree with the duplication as it does not answer the question fully. Will the compiler generate other constructors in the second case? – pingul Jun 29 '16 at 23:15
  • 4
    "*The purpose of me asking is if I can expect move/copy constructors and assignment operators being automatically generated.*" It should be noted that the presence or absence of a trivial default constructor has nothing to do with move/copy constructors/operators being generated. – Nicol Bolas Jun 29 '16 at 23:19
  • @NicolBolas Do you mean in the sense that they can be explicitly generated by `A(const A&) = default;`, or is there another reason? I thought they were implicitly generated if the default constructor was. – pingul Jun 29 '16 at 23:22
  • @pingul: No, I mean in every sense. The triviality of the default constructor has no bearing on the compiler-generated move/copy constructors/operators or the destructor. – Nicol Bolas Jun 29 '16 at 23:35

1 Answers1

8

Is the following constructor considered trivial?

A() : a(nullptr) {}

No, because it is user-defined.

struct A
{
private:
    int* a{nullptr};
};

No, because it has brace initializer for a non-static member.

According to the standard (emphasis mine):

12.1 Constructors
....

A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.40).
....

A default constructor is trivial if it is not user-provided and if:
....
no non-static data member of its class has a brace-or-equal-initializer, and
....

Otherwise, the default constructor is non-trivial.


The purpose of me asking is if I can expect move/copy constructors and assignment operators being automatically generated.

As @M.M and @NicolBolas commented, generation of these constructors and operators are not impacted by existence of the trivial constructor.

The rules are a bit complicated and not very consistent.

The copy constructor is generated only if there is no explicitly declared one. (And it is deleted if the move constructor or the move assignment operator is declared.)

Similarly, the copy assignment operator is generated only if there is no explicitly declared one. (And again, it is deleted if the move constructor or the move assignment operator is declared.)

The move constructor is generated only if there are no explicitly declared move constructor, move operator, copy constructor, copy assignment and destructor.

The same rule is for the move assignment operator.

AlexD
  • 32,156
  • 3
  • 71
  • 65
  • Another weird caveat is that a constructor that is declared inline and then = default in the .cpp file, is still not considered trivial. I guess technically it is "user declared" at that point, but it's a weird edge case and weird they decided to say "user declared" and not "user defined". – Nir Friedman May 12 '17 at 08:32