C++ 如何初始化由唯一\u ptr管理的数组元素?

C++ 如何初始化由唯一\u ptr管理的数组元素?,c++,c++11,std,unique-ptr,C++,C++11,Std,Unique Ptr,我们知道资源获取就是初始化(RAII),我寻找语法来初始化一个由unique\u ptr管理的具有参数(没有默认参数)的对象数组,但是我没有找到任何示例,在cppint中有一个 int size = 10; std::unique_ptr<int[]> fact(new int[size]); int size=10; std::unique_ptr事实(新int[size]); 我怎么能这样写: class Widget { Widget(int x, in y):x_(x

我们知道资源获取就是初始化(RAII),我寻找语法来初始化一个由
unique\u ptr
管理的具有参数(没有默认参数)的对象数组,但是我没有找到任何示例,在cppint中有一个

int size = 10; 
std::unique_ptr<int[]> fact(new int[size]);
int size=10;
std::unique_ptr事实(新int[size]);
我怎么能这样写:

class Widget
{
 Widget(int x, in y):x_(x),y_(y)
 {}
 int x_,y_;
};

 std::unique_ptr<Widget[]> fact(new Widget[size]);
类小部件
{
小部件(int x,in y):x_ux(x),y_y(y)
{}
int x_uux,y_uux;
};
std::unique_ptr事实(新小部件[size]);

根据推荐链接中的最后一个答案,
我想出了以下小例子:

#include <iostream>
#include <memory>
#include <string>

class Widget {
  private:
    std::string _name;
  public:
    Widget(const char *name): _name(name) { }
    Widget(const Widget&) = delete;
    const std::string& name() const { return _name; }
};

int main()
{
  const int n = 3;
  std::unique_ptr<Widget[]> ptrLabels(
    new Widget[n]{
      Widget("label 1"),
      Widget("label 2"),
      Widget("label 3")
    });
  for (int i = 0; i < n; ++i) {
    std::cout << ptrLabels[i].name() << '\n';
  }
  return 0;
}

诀窍是使用初始值设定项列表

我有点不确定这是否涉及复制构造(在小部件类库中经常被禁止)。当然,我写了
Widget(constwidget&)=delete

我必须承认,这在C++17上是可行的,但在以前是不行的


我对第一个例子稍加修改

我也试过了

new Widget[n]{
  { "label 1" },
  { "label 2" },
  { "label 3" }
});
直到我意识到在第一个示例中我忘记了显式地创建构造函数。(通常,小部件集不允许这样做,以防止意外转换。)修复后,它不再编译

介绍了一种即使使用C++11也能编译的移动构造函数:

#include <iostream>
#include <memory>
#include <string>

class Widget {
  private:
    std::string _name;
  public:
    explicit Widget(const char *name): _name(name) { }
    Widget(const Widget&) = delete;
    Widget(const Widget &&widget): _name(std::move(widget._name)) { }
    const std::string& name() const { return _name; }
};

int main()
{
  const int n = 3;
  std::unique_ptr<Widget[]> ptrLabels(
    new Widget[n]{
      Widget("label 1"),
      Widget("label 2"),
      Widget("label 3")
    });
  for (int i = 0; i < n; ++i) {
    std::cout << ptrLabels[i].name() << '\n';
  }
  return 0;
}
#包括
#包括
#包括
类小部件{
私人:
std::string _name;
公众:
显式小部件(const char*name):\u name(name){}
小部件(常量小部件&)=删除;
小部件(常量小部件和小部件):_name(std::move(小部件._name)){}
常量std::string&name()常量{return\u name;}
};
int main()
{
常数int n=3;
std::唯一的\u ptr ptrLabels(
新部件[n]{
小部件(“标签1”),
小部件(“标签2”),
小部件(“标签3”)
});
对于(int i=0;istd::cout您可以使用placement new和custom deleter:

class Widget {
public:
    int i;
    Widget(int i) : i(i) {}
    ~Widget() { std::cout << i; }
};

class WidgetDeleter {
    int _size;
public:
    WidgetDeleter(int size) : _size(size) {}
    void operator()(Widget* w) { 
        for (int i = 0; i < _size; ++i) w[i].~Widget();
    }
}; 

void main() {
    const int widgetsCount = 10;
    auto widgets = std::unique_ptr<Widget[], WidgetDeleter>(
        (Widget*)(new byte[widgetsCount * sizeof(Widget)]), WidgetDeleter(widgetsCount));
    for (int i = 0; i < widgetsCount; ++i) new (widgets.get() + i)Widget(i);
    for (int i = 0; i < widgetsCount; ++i) std::cout << widgets[i].i;
    std::cout << std::endl;
}
类小部件{
公众:
int i;
小部件(inti):i(i){}

~Widget();我需要用参数初始化对象如果
小部件的构造函数
可能引发异常,那么什么呢?你的代码将变得非常复杂,以确保异常安全。最后,你只需手动实现
std::vector
为你提供的内容。@DanielLangr我同意这样的代码应该仔细编写并驻留在libra中里。