title: How to use a std::vector<unique_ptr<T>> as default parameter
body: <h2>EDIT2:</h2>
  <h3>To clarify:</h3>
  <p>This question originated from a problem that actually had nothing to do with default parameters themselves, but copy- and move-constructors.
  I accepted the answer that actually answers the question (so if you are here because of the question title, read it) and will explain why it didn't work for me initially.</p>
  <h2>What was the problem?</h2>
  <p>So the problem, as described under &quot;EDIT:&quot;, is actually fairly simple:</p>
  <p>An assignment to a class containing a <code>std::vector&lt;std::unique_ptr&lt;T&gt;&gt;</code> will break compilation in VisualStudio 2013 (not tested with other versions) and the error messages are extremely cryptic.</p>
  <p>Assumptions in the comments were that the VC compiler had a bug and tried to call a copy constructor which didn't exist.</p>
  <h2>Shit, what now?</h2>
  <p>This assumption was in fact true, but not in the sense I first understood it.</p>
  <p>Actually, the VCC <em>does</em> in fact try to call the move constructor of <code>MyClass</code>, which it does implicitly define. <em>But</em>, and this is where the problem lies, it doesn't define it <em>correctly</em>:</p>
  <p>When defining the move constructor <code>MyClass(MyClass &amp;&amp; a)</code> explicitly, we can actually imitate the behaviour of the compiler by writing our code like this:</p>
  <pre><code>MyClass(MyClass &amp;&amp; a)
      : foos_(a.foos_)
  {}
  </code></pre>
  <p>Using this code generates <em>the exact same error messages</em> as using the implicit definition, and I guess
  you can immediately see what's wrong here: this move constructor actually tries to call the copy constructor of <code>foos_</code>, which of course isn't possible, because it in turn can't call a copy constructor for its contents, as those are of type <code>std::unique_ptr</code> which <em>doesn't have</em> a copy constructor for obvious reasons.</p>
  <p>When instead using this code,</p>
  <pre><code>MyClass(MyClass &amp;&amp; a)
      : foos_(std::move(a.foos_))
  {}
  </code></pre>
  <p>everything works out perfectly fine, because now the move constructor of <code>std::vector</code> is called and thus the move constructor for its contents.</p>
  <h2>So who's to blame?</h2>
  <h3>Possibility 1:</h3>
  <p>It is in fact a compiler-bug and originates from a template resolving issue.</p>
  <p>The compiler wants to implicitly define a move-constructor if needed, and it does so if there are non-copyable types in the class definition and if an assignment to that class is ever made in the code.</p>
  <p>If these two conditions are satisfied, it proceeds to define the move-constructor, but now doesn't seem to care about the actual type of the <code>std::vector</code> template, only about the class itself, which does indeed define a copy<code>constructor, so the VCC tries to use it, which fails because of the missing copy constructor in </code>std::unique_ptr`.</p>
  <p>Or, it just skips the definition of the move-constructor entirely and tries to use the copy-constructor, which leads to the same error.</p>
  <h3>Possibility 2:</h3>
  <p>Something fishy in the Microsoft STL implementation. This is only a clue and I couldn't explain how it worked exactly, but it seems to be a possibility to me regardless.</p>
  <h2>How to avoid this mess?</h2>
  <p>Easy, define your own move constructor as shown above.</p>
  <hr />
  <h2>EDIT:</h2>
  <h3>It seems to come down to one particular problem, the original answer is posted below.</h3>
  <p>In Visual Studio (2013), create a fresh Win32 console application, don't change any settings and make this your main <code>.cpp</code>:</p>
  <pre><code>// ConsoleApplication2.cpp : Defines the entry point for the console application.
  //
  
  #include &quot;stdafx.h&quot;
  
  #include &lt;vector&gt;
  #include &lt;memory&gt;
  
  class Foo { };
  
  class MyClass
  {
  public:
      MyClass(std::vector&lt;std::unique_ptr&lt;Foo&gt;&gt; foos) :
          foos_(std::move(foos))
      {};
  
      std::vector&lt;std::unique_ptr&lt;Foo&gt;&gt; foos_;
  };
  
  int _tmain(int argc, _TCHAR* argv[])
  {
      auto test = MyClass(std::vector&lt;std::unique_ptr&lt;Foo&gt;&gt;()); //remove this, and all works fine!
      return 0;
  }
  </code></pre>
  <p>Trying to compile it will result in the following error (It definitely works with gcc!):</p>
  <pre><code>1&gt;  ConsoleApplication2.cpp
  1&gt;c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(593): error C2280: 'std::unique_ptr&lt;Foo,std::default_delete&lt;_Ty&gt;&gt;::unique_ptr(const std::unique_ptr&lt;_Ty,std::default_delete&lt;_Ty&gt;&gt; &amp;)' : attempting to reference a deleted function
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=Foo
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr&lt;Foo,std::default_delete&lt;_Ty&gt;&gt;::unique_ptr'
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=Foo
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(592) : while compiling class template member function 'void std::allocator&lt;_Ty&gt;::construct(_Ty *,const _Ty &amp;)'
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=std::unique_ptr&lt;Foo,std::default_delete&lt;Foo&gt;&gt;
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator&lt;_Ty&gt;::construct(_Ty *,const _Ty &amp;)' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=std::unique_ptr&lt;Foo,std::default_delete&lt;Foo&gt;&gt;
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(572) : see reference to class template instantiation 'std::allocator&lt;_Ty&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=std::unique_ptr&lt;Foo,std::default_delete&lt;Foo&gt;&gt;
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(650) : see reference to class template instantiation 'std::is_empty&lt;_Alloc&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Alloc=std::allocator&lt;std::unique_ptr&lt;Foo,std::default_delete&lt;Foo&gt;&gt;&gt;
  1&gt;          ]
  1&gt;          c:\users\felix\source\repos\infinite whitewursht\infinitewhitewursht\consoleapplication2\consoleapplication2.cpp(18) : see reference to class template instantiation 'std::vector&lt;std::unique_ptr&lt;Foo,std::default_delete&lt;_Ty&gt;&gt;,std::allocator&lt;std::unique_ptr&lt;_Ty,std::default_delete&lt;_Ty&gt;&gt;&gt;&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=Foo
  1&gt;          ]
  </code></pre>
  <hr />
  <p>Suppose I have a constructor like this:</p>
  <pre><code>MyClass(vector&lt;unique_ptr&lt;Foo&gt;&gt; foos) :
      foos_(std::move(foos))
  {};
  </code></pre>
  <p>With this simple setup, everything compiles fine.
  A call to this constructor like <code>MyClass(vector&lt;unique_ptr&lt;Foo&gt;&gt;);</code> succeeds and behaves as expected. But I'd like to have <code>foos</code> as a default parameter.</p>
  <p><em>How can I achieve a default value for <code>foos</code>?</em></p>
  <p>This is what I came up with:</p>
  <pre><code>MyClass(vector&lt;unique_ptr&lt;Foo&gt;&gt; foos = vector&lt;unique_ptr&lt;Foo&gt;&gt;()) :
      foos_(std::move(foos))
  {};
  </code></pre>
  <p>But unfortunately, this doesn't work. I don't know why, it would be nice if somebody could shed some light on this.</p>
  <p>Next two tries, which are workarounds, not actual default parameters:</p>
  <pre><code>MyClass() :
      foos_() //or foos_(vector&lt;unique_ptr&lt;Foo&gt;&gt;())
  {};
  </code></pre>
  <p>Don't work either. Both these approaches lead to an error message from the compiler and a lengthy output which most interesting part is this:</p>
  <blockquote>
  <p>c:\users\ <em>username</em> \source\repos\myProject\myProject\MyClass.h(47) : see reference to class template instantiation</p>
  </blockquote>
  <p>Where the 47 is the line number of the actual vector definition in <code>MyClass</code>:</p>
  <pre><code>vector&lt;unique_ptr&lt;GameObject&gt;&gt; foos_;
  </code></pre>
  <p>So my guess would be that this really is about me doing a huge mistake with the initialization.</p>
  <p>Also, I am compiling on VS2013.</p>
  <p>The whole error:</p>
  <pre><code>GameObject.cpp
  1&gt;c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(593): error         C2280: 'std::unique_ptr&lt;int,std::default_delete&lt;_Ty&gt;&gt;::unique_ptr(const std::unique_ptr&lt;_Ty,std::default_delete&lt;_Ty&gt;&gt; &amp;)' : attempting to reference a deleted function
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=int
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr&lt;int,std::default_delete&lt;_Ty&gt;&gt;::unique_ptr'
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=int
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(592) : while compiling class template member function 'void std::allocator&lt;_Ty&gt;::construct(_Ty *,const _Ty &amp;)'
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=std::unique_ptr&lt;int,std::default_delete&lt;int&gt;&gt;
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator&lt;_Ty&gt;::construct(_Ty *,const _Ty &amp;)' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=std::unique_ptr&lt;int,std::default_delete&lt;int&gt;&gt;
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(572) : see reference to class template instantiation 'std::allocator&lt;_Ty&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=std::unique_ptr&lt;int,std::default_delete&lt;int&gt;&gt;
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(650) : see reference to class template instantiation 'std::is_empty&lt;_Alloc&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Alloc=std::allocator&lt;std::unique_ptr&lt;int,std::default_delete&lt;int&gt;&gt;&gt;
  1&gt;          ]
  1&gt;          c:\users\felix\source\repos\infinite whitewursht\infinitewhitewursht\infinitewhitewursht\gameobject.h(47) : see reference to class template instantiation 'std::vector&lt;std::unique_ptr&lt;int,std::default_delete&lt;_Ty&gt;&gt;,std::allocator&lt;std::unique_ptr&lt;_Ty,std::default_delete&lt;_Ty&gt;&gt;&gt;&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=int
  1&gt;          ]
  </code></pre>