为什么我不能使用auto声明变量?

And*_*ndy 4 c++ visual-c++ move-semantics c++11 visual-studio-2015

当我尝试声明类的变量时,我在Visual Studio 2015中遇到编译错误,当这些类使用PIMPL模式时.

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;
};
Run Code Online (Sandbox Code Playgroud)

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)
{
}
Run Code Online (Sandbox Code Playgroud)

如果我Foo使用传统语法声明一个类型的变量,它编译很好:

  Foo f(L"Hello", std::vector<std::wstring>());
Run Code Online (Sandbox Code Playgroud)

但是,如果我声明它使用auto,那么我得到一个编译错误:

  auto f2 = Foo { L"Goodbye", std::vector<std::wstring>() };
Run Code Online (Sandbox Code Playgroud)

错误C2280:'Foo :: Foo(const Foo&)':尝试引用已删除的函数
注释:编译器已在此处生成'Foo :: Foo'

我明白Foo应该删除复制构造函数,因为unique_ptr无法复制.但是,我的理解是,当以这种方式声明变量时,结果将被移入变量或直接将值设置到变量中.

使用Visual Studio 2013时,第二行编译得很好.我检查了Visual Studio 2015中的重大更改,但我没有看到任何可以指示为什么开始失败的内容.

我做错了什么,或者这种语法不能与不可复制的类型一起使用?

Col*_*mbo 10

移动构造函数不是隐式声明的,因为你有一个用户声明的析构函数(参见[class.copy] /(9.4)).但是,复制构造函数被清楚地删除,因为unique_ptr无法复制.

您可以显式声明移动构造函数为默认值.


Som*_*ude 5

因为类包含std::unique_ptr成员,所以编译器不能像通常那样生成复制构造函数,这意味着您的声明和初始化(调用复制构造函数)将无法实现.

您可以通过为类创建移动构造函数并将其标记为来解决此问题default.