I'm getting a compile error in Visual Studio 2015 when I try to declare a variable of class, when that classes uses the PIMPL pattern.
Foo.h:
#pragma once
class Foo
{
public:
Foo(const std::wstring& str,
const std::vector<std::wstring>& items);
~Foo();
private:
struct Impl;
std::unique_ptr<Impl> pimpl;
};
Foo.cpp:
#include "stdafx.h"
#include "Foo.h"
struct Foo::Impl
{
public:
Impl(const std::wstring& str,
const std::vector<std::wstring>& items);
std::wstring str_;
std::vector<std::wstring> items_;
};
Foo::Foo(const std::wstring& str,
const std::vector<std::wstring>& items)
: pimpl(std::make_unique<Impl>(str, items))
{
}
Foo::~Foo() = default;
Foo::Impl::Impl(const std::wstring& str,
const std::vector<std::wstring>& items)
: str_(str),
items_(items)
{
}
If I declare a variable of type Foo
using the traditional syntax, it compiles fine:
Foo f(L"Hello", std::vector<std::wstring>());
However, if I declare it using auto
, then I get a compile error:
auto f2 = Foo { L"Goodbye", std::vector<std::wstring>() };
error C2280: 'Foo::Foo(const Foo &)': attempting to reference a deleted function
note: compiler has generated 'Foo::Foo' here
I understand that the copy constructor for Foo
should be deleted, since unique_ptr
can't be copied. However, it was my understanding that when declaring variables in this way, the result would be either moved into the variable or just set the value into the variable directly.
The second line compiles fine when using Visual Studio 2013. I checked the breaking changes in Visual Studio 2015, but I didn't see anything there that would indicate why this started failing.
Am I doing something wrong, or can this syntax not be used with non-copyable types?