6

Consider the following:

template <class T>
struct myclass
{
    using value_type = T;
    constexpr myclass() = default;
    constexpr myclass(const myclass& other) = default;
    constexpr myclass(const myclass&& other) = default;
    T value;
};
  • To what constructor bodies these function are equivalent?
  • Does myclass<int> x; initialize the integer at 0?
  • For myclass<std::vector<int>> x; what does the default move constructor do? Does it call the move constructor of the vector?
M.M
  • 138,810
  • 21
  • 208
  • 365
Vincent
  • 57,703
  • 61
  • 205
  • 388

1 Answers1

6

They aren't equivalent to any function bodies. There are small but significant differences between the three cases: = default, allowing implicit generation, and the nearest equivalent function body.

The following links explain in more detail:

I couldn't find a good link about copy-constructor; however similar considerations as mentioned in the other two links will apply.


myclass<int> x; does not set value to 0.

The defaulted move-constructor (if you made it a non-const reference) moves each movable member (although I think there is a special case where if there is a non-movable base class, weird things happen...)

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • IIRC, if there is a non-moveable base or non-static data member, the explicitly defaulted move constructor will be defined as deleted. – Praetorian Nov 30 '15 at 20:54
  • @Praetorian could you answer [this question](http://stackoverflow.com/questions/33988934/why-are-implicitly-and-explicitly-deleted-move-constructors-treated-differently?noredirect=1#comment55747826_33988934) from yesterday? I wasn't able to grok what was going on, the `ImplicitDelete` class has a non-movable base, but moving it does compile – M.M Nov 30 '15 at 20:56
  • I don't know the *why* part, but the OP's description is correct - *[class.copy]/11 - A defaulted move constructor that is defined as deleted is ignored by overload resolution*. So `ImplicitDelete`'s move constructor is ignored by overload resolution and the copy constructor is the next viable candidate, so moving it will result in copying. – Praetorian Nov 30 '15 at 21:04
  • @Praetorian ok, thanks for that. So there is an exception to the rule that deleted functions participate in overload resolution.. clear as mud :) – M.M Nov 30 '15 at 21:06
  • Are you sure that `myclass x;` does not set value to `0`? If I use the value without initialization, neither g++ or clang++ give me a warning (and in both cases, it is set to 0). – Vincent Nov 30 '15 at 21:36
  • 2
    @Vincent Yes I'm sure. Compiler warnings are irrelevant. Trying to output an uninitialized variable causes undefined behaviour, you might see anything. See [dcl.init]/12 of C++14 – M.M Nov 30 '15 at 21:41
  • [This example](http://coliru.stacked-crooked.com/a/e16e2bc8a432ec81) currently shows non-zero for me... results may vary between runs of course – M.M Nov 30 '15 at 21:48