Be careful to use default constructors only. And only those generated by the compiler.
The Godbolt with the code from this post. And also the post “from before”, I slightly refactored to follow the advice from here.
Here is the explanation. Let’s start, with your type:
1 2 3 |
// my type struct MyType { } ; |
Your trusty C++ compiler generates the default constructor.
1 2 3 4 5 |
// MyType * my_type_made_on_the_heap = new MyType(); // MyType my_type_made_on_the_stack ; |
All other constructors are evil. Firstly, because you can not return the result you need from a constructor. That is especially “not a good thing” if you want to avoid exceptions.
A default constructor is a constructor which can be called with no arguments (either defined with an empty parameter list, or with default arguments provided for every parameter). A type with a public default constructor is DefaultConstructible.
cppreference.com
What is the key conceptual problem with a constructor? It can not return a value. An exception is an official way to signal the error. And exceptions are bad. Exceptions are conceptually wrong and performance detrimental.
Nondefault constructors are completely unnecessary. Path peppered with shards of glass.
Take control of your life. Use factory methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// struct MyType { int payload ; // by default make on stack static MyType make (int val) { MyType retval; retval.payload = val ; return retval ; } }; int main(void) { return MyType::make(42).payload ; } |
I might be so bold to advise: always check if your types are “Default Constructible“.
1 2 3 4 5 6 |
// compile time checks cost nothing // always do this static_assert(std::is_default_constructible_v<MyType> ); static_assert(std::is_nothrow_default_constructible_v<MyType> ); // and this too static_assert(std::is_trivially_default_constructible_v<MyType> ); |
I very much doubt this advice can be followed as it is, due to the standard obfuscation of standard C++. In any case, try and avoid non-trivial constructors at any cost.
Non-default constructors are one of the mortal mistakes of C++.
A non-trivial Godbolt example.