标签: unique-ptr

为什么`make_unique <T [N]>`不允许?

std全程假设命名空间.

因此,C++ 14委员会草案N3690定义std::make_unique如下:

[n3690: 20.9.1.4]: unique_ptr创作    [unique.ptr.create]

template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);

1备注:除非T不是数组,否则此函数不应参与重载决策.
2返回:unique_ptr<T>(new T(std::forward<Args>(args)...)).

template <class T> unique_ptr<T> make_unique(size_t n);

3备注:除非T是未知范围的数组,否则此函数不应参与重载决策.
4返回:unique_ptr<T>(new typename remove_extent<T>::type[n]()).

template <class T, class... Args> unspecified make_unique(Args&&...) = delete;

5备注:除非T是已知绑定的数组,否则此函数不应参与重载决策.

现在,在我看来,这与泥浆一样清晰,我认为需要更多的阐述.但是,除了这篇评论之外,我相信我已经解释了每个变体的含义:

  1. template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);

    make_unique的非数组类型的标准.据推测,"注释"表示某种形式的静态断言或SFINAE技巧是为了防止模块在T数组类型时被成功实例化.

    在高级别,将其视为相当于的智能指针T* ptr = new T(args);.

  2. template <class T> …

c++ unique-ptr language-lawyer c++14

26
推荐指数
1
解决办法
3494
查看次数

我应该使用shared_ptr还是unique_ptr?

我有一个关于std::unique_ptr和的问题std::shared_ptr.我知道有很多关于何时使用哪一个的问题,但我仍然不确定我是否正确理解它.我在某处读到了智能指针的默认选择std::unique_ptr,但据我了解,我应该更喜欢使用std::shared_ptr.例如,我有:

class B;
class A
{
private:
   B* b;
public:
   B* getB();
};

A::getB()
{
   return b;
}
Run Code Online (Sandbox Code Playgroud)

所以基本上类A拥有指向类型对象的指针,B并且有一个返回该指针的方法.如果我创建了getter,我假设其他一些类可以访问这个指针,因此它应该shared_ptr代替unique_ptr.我是对的,还是我还没有得到它?

c++ smart-pointers shared-ptr unique-ptr c++11

25
推荐指数
2
解决办法
2万
查看次数

unique_ptr和shared_ptr的重载方法与多态性不一致

在我从前一个问题的答案中提示之后编写了一些东西,我遇到了重载Scene :: addObject的问题.

重申相关位并使其自包含,尽可能少的细节:

  • 我有继承对象的层次Interface,其中有FooS和BarS;
  • 我有一个Scene拥有这些物品的人;
  • Foos应该是unique_ptrs和Bars将shared_ptr在我的主要(由于前一个问题中解释的原因);
  • main它们传递到Scene实例,其取得所有权.

最小的代码示例是这样的:

#include <memory>
#include <utility>

class Interface
{
public:
  virtual ~Interface() = 0;
};

inline Interface::~Interface() {}

class Foo : public Interface
{
};

class Bar : public Interface
{
};

class Scene
{
public:
  void addObject(std::unique_ptr<Interface> obj);
//  void addObject(std::shared_ptr<Interface> obj);
};

void Scene::addObject(std::unique_ptr<Interface> obj)
{
}

//void …
Run Code Online (Sandbox Code Playgroud)

c++ overloading shared-ptr unique-ptr c++14

25
推荐指数
2
解决办法
1305
查看次数

C++ unique_ptr和map

我正在尝试使用C++ 0x unique_ptr,map如下所示:

// compile with `g++ main.cpp -std=gnu++0x`

#include <string.h>    
#include <map>
#include <memory>

using namespace std;

struct Foo {
    char *str;    
    Foo(char const *str_): str(strdup(str_)) {}
};

int main(void) {
    typedef std::map<int, unique_ptr<Foo>> Bar;
    Bar bar;
    auto a = bar.insert(Bar::value_type(1, new Foo("one")));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是GCC给了我以下错误(缩短了,我认为这是相关部分,请在您自己的C++编译器上测试):

main.cpp:19:   instantiated from here
/usr/include/c++/4.4/bits/unique_ptr.h:214: error: deleted function ‘std::unique_ptr::unique_ptr(const std::unique_ptr&) [with _Tp = Foo, _Tp_Deleter = std::default_delete]’
/usr/include/c++/4.4/bits/stl_pair.h:68: error: used here

我真的不确定我做错了什么,这适用于MSVC.我发现了非常相似的问题,看似相似,但是他们的解决方案对我不起作用.

matt@stanley:/media/data/src/c++0x-test$ gcc --version …

c++ gcc stl unique-ptr c++11

24
推荐指数
2
解决办法
2万
查看次数

通过传递指针的地址来初始化std :: unique_ptr

我正在创建一个与一些Windows API代码交互的类,现在我必须初始化的一个指针是通过调用初始化它的本机函数来完成的.

我的指针是std::unique_ptr带有自定义删除器的类型,它调用所提供的WinAPI删除函数,但是我不能将带有&address-of运算符的unique_ptr传递给init-function.为什么?

我创建了一个演示我的问题的示例:

#include <memory>

struct foo
{
   int x;
};

struct custom_deleter {};

void init_foo(foo** init)
{
  *init = new foo();
}

int main()
{
   std::unique_ptr<foo, custom_deleter> foo_ptr;

   init_foo(&foo_ptr);
}
Run Code Online (Sandbox Code Playgroud)

编译器咆哮并说:

source.cpp: In function 'int main()':
source.cpp:19:21: error: cannot convert 'std::unique_ptr<foo, custom_deleter>*' to 'foo**' for argument '1' to 'void init_foo(foo**)'
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr c++11

24
推荐指数
2
解决办法
3万
查看次数

应该允许std :: unique_ptr <void>

这是一个非常简单的问题.请考虑以下代码:

#include <iostream>
#include <memory>

typedef std::unique_ptr<void> UniqueVoidPtr;

int main() {
    UniqueVoidPtr p(new int);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用以下命令使用cygwin(g ++ 4.5.3)进行编译g++ -std=c++0x -o prog file.cpp就可以了.但是,使用Microsoft编译器(VS 2010或2013)进行编译时出现此错误:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2067) : error C2070: 'void': illegal sizeof operand
        C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2066) : while compiling class template member function 'void std::default_delete<_Ty>::operator ()(_Ty *) const'
        with
        [
            _Ty=void
        ]
        C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\type_traits(650) : see reference to class template instantiation 'std::default_delete<_Ty>' being compiled
        with
        [ …
Run Code Online (Sandbox Code Playgroud)

c++ gcc visual-studio-2010 unique-ptr c++11

24
推荐指数
3
解决办法
9187
查看次数

删除器类型在unique_ptr与shared_ptr中

当我发现标准定义std::unique_ptr并且std::shared_ptr以两种完全不同的方式关于指针可能拥有的Deleter时,我认为这很奇怪.这是来自cppreference :: unique_ptrcppreference :: shared_ptr的声明:

template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;

template< class T > class shared_ptr;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,unique_ptr将"Deleter"对象的类型"保存"为模板参数.这也可以通过稍后从指针中检索Deleter的方式看出:

// unique_ptr has a member function to retrieve the Deleter
template<
    class T,
    class Deleter = std::default_delete<T>
>
Deleter& unique_ptr<T, Deleter>::get_deleter();

// For shared_ptr this is not a member function
template<class Deleter, class T>
Deleter* get_deleter(const std::shared_ptr<T>& p);
Run Code Online (Sandbox Code Playgroud)

有人可以解释这种差异背后的理性吗?我明显赞成这个概念,unique_ptr为什么这不适用于此shared_ptr?另外,为什么get_deleter在后一种情况下会成为非成员函数呢?

c++ shared-ptr unique-ptr c++11

24
推荐指数
1
解决办法
3755
查看次数

析构函数和unique_ptr

我有以下代码

class A {
    public:
        A(){}
        ~A(){}
    private:
        std::vector<std::unique_ptr<double> > x;
};

A f() {
    A a;
    return a;
}

int main() {
    A a=f();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

除非我注释掉析构函数,否则它不会编译(gcc 4.7).实际上,我在代码中并不需要这个析构函数,我只是想将它用于调试目的.

但是,我不明白发生了什么,因此我担心我做错了什么.这里发生了什么?

c++ unique-ptr c++11

23
推荐指数
1
解决办法
4794
查看次数

C++ std :: unique_ptr从函数返回并测试为null

我有一个函数需要返回一个指向类对象的指针myClass.为此我正在使用std::unique_ptr.

如果函数成功,它将返回一个指向带有数据的对象的指针.如果失败,它应该返回null.

这是我的代码skelepton:

std::unique_ptr<myClass> getData()
{
   if (dataExists)
      ... create a new myClass object, populate and return it ...

   // No data found
   return std::unique_ptr<myClass> (null); <--- Possible ?
}
Run Code Online (Sandbox Code Playgroud)

main:

main()
{
   std::unique_ptr<myClass> returnedData;

   returnedData = getData();

   if (returnedData != null)   <-- How to test for null ?
   {
      cout << "No data returned." << endl;
      return 0;
   }

   // Process data
}
Run Code Online (Sandbox Code Playgroud)

所以这里是我的问题:

a)是否null可以使用std::unique_ptr?(返回一个对象或)?

b)如果可能,如何实施?

c)如果不可能,有哪些替代方案? …

c++ unique-ptr c++11

23
推荐指数
3
解决办法
5万
查看次数

了解复制初始化和隐式转换

我无法理解为什么以下复制初始化无法编译:

#include <memory>

struct base{};
struct derived : base{};

struct test
{
    test(std::unique_ptr<base>){}
};

int main()
{
    auto pd = std::make_unique<derived>();
    //test t(std::move(pd)); // this works;
    test t = std::move(pd); // this doesn't
}
Run Code Online (Sandbox Code Playgroud)

A unique_ptr<derived>可以移入a unique_ptr<base>,那么为什么第二个语句有效但最后一个没有?执行复制初始化时是否不考虑非显式构造函数?

gcc-8.2.0的错误是:

conversion from 'std::remove_reference<std::unique_ptr<derived, std::default_delete<derived> >&>::type' 
{aka 'std::unique_ptr<derived, std::default_delete<derived> >'} to non-scalar type 'test' requested
Run Code Online (Sandbox Code Playgroud)

从clang-7.0.0开始

candidate constructor not viable: no known conversion from 'unique_ptr<derived, default_delete<derived>>' 
to 'unique_ptr<base, default_delete<base>>' for 1st argument
Run Code Online (Sandbox Code Playgroud)

现场代码可在此处获得.

c++ unique-ptr implicit-conversion c++17

23
推荐指数
2
解决办法
970
查看次数