c++ - 为什么需要 std::make_unique 来初始化成员 std::unique 数组,以及如何解决 C++11 问题?

标签 c++ c++11 stl unique-ptr

在下面的代码中,为什么是std::make_unique需要初始化 Foo::up_ ?
具体来说,为什么不初始化 Foo::up_new Bar(...) -- 就像注释掉的代码一样 -- 行得通吗?

#include <iostream>
#include <memory>

enum E {
  Y = 0,
  Z = 1,
  NUM_E
};

class Bar {
public: // Functions
  Bar( const int& i, const int& j ) : i_(i), j_(j) { }

public: // Objects
  int i_;
  int j_;
};

class Foo {
public: // Functions
  Foo();

  void reset( const int& Yi, const int& Yj,
              const int& Zi, const int& Zj );

public: // Objects
  std::unique_ptr<Bar> up_[NUM_E];
};

Foo::Foo()
  : up_{ std::make_unique<Bar>( 42, 43 ),
         std::make_unique<Bar>( 44, 45 ) }
//  : up_{ new Bar( 42, 43 ),
//         new Bar( 44, 45 ) } // err: could not convert from Bar* to unique_ptr
{ }

void Foo::reset( const int& Yi, const int& Yj,
                 const int& Zi, const int& Zj ) {
  up_[Y].reset( new Bar( Yi, Yj ) );
  up_[Z].reset( new Bar( Zi, Zj ) );
}

int main( int argc, char* argv[] ) {
  (void)argc;
  (void)argv;
  Foo foo;

  std::cout << foo.up_[Y]->i_ << std::endl;
  std::cout << foo.up_[Y]->j_ << std::endl;
  std::cout << foo.up_[Z]->i_ << std::endl;
  std::cout << foo.up_[Z]->j_ << std::endl;

  foo.reset( 1, 2, 3, 4 );

  std::cout << foo.up_[Y]->i_ << std::endl;
  std::cout << foo.up_[Y]->j_ << std::endl;
  std::cout << foo.up_[Z]->i_ << std::endl;
  std::cout << foo.up_[Z]->j_ << std::endl;

  return 0;
}
$ g++ --version && g++ --std=c++14 ./main.cpp && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

42
43
44
45
1
2
3
4

如何为 C++11 解决这个问题? , 其中std::make_unique似乎没有空?

$ g++ --version && g++ --std=c++11 ./main.cpp && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

./main.cpp: In constructor ‘Foo::Foo()’:
./main.cpp:31:10: error: ‘make_unique’ is not a member of ‘std’
   : up_{ std::make_unique<Bar>( 42, 43 ),
          ^~~
./main.cpp:31:30: error: expected primary-expression before ‘>’ token
   : up_{ std::make_unique<Bar>( 42, 43 ),
                              ^
./main.cpp:32:10: error: ‘make_unique’ is not a member of ‘std’
          std::make_unique<Bar>( 44, 45 ) }
          ^~~
./main.cpp:32:30: error: expected primary-expression before ‘>’ token
          std::make_unique<Bar>( 44, 45 ) }
                              ^

最佳答案

1.构造函数 unique_ptr( pointer p ) 标记为 explicit ,它可以防止 unique_ptr 的实例从在数组列表初始化中隐式构造。

2。 std::make_unique从 C++14 开始可用。

在 C++11 中,对这两点的一个可能解决方案是显式构造一个实例,例如std::unique_ptr<Bar>(new Bar( 42, 43 )) .

关于c++ - 为什么需要 std::make_unique 来初始化成员 std::unique 数组,以及如何解决 C++11 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66481425/

相关文章:

c++ - 仅抑制实际的 make 命令和最终的 print 语句

c++ - 填充数组

c++ - Cuda C++ 内存包装器类

c++ - 检查 ofRay 是否与 ofMeshFace 相交

c++ - 使用专门函数的异构集合的 STL 算法

c++ - QFontMetrics boundingRect

c++ - 将 boost::make_recursive_variant 与元组一起使用

c++ - 等待多个互斥锁的条件变量

c++ - 如何在 noexcept 运算符中引用移动构造函数

c++ - 在 C++ STL 中,如何使用 regex_replace 从 std::string 中删除非数字字符?