标签: unique-ptr

迭代unique_ptr的容器

如何在不从容器中取得所有权的情况下访问容器的unique_ptr元素(通过迭代器)?当一个人获得容器中元素的迭代器时,元素所有权仍然与容器有关吗?当一个解引用迭代器来获取对unique_ptr的访问权限时怎么样?这是否执行unique_ptr的隐式移动?

当我需要将元素存储在容器中(而不是通过值)时,我发现我正在使用shared_ptr,即使容器在概念上拥有元素而其他代码只是希望操纵容器中的元素,因为我害怕无法实际访问容器中的unique_ptr元素而不从中获取所有权.

任何见解?

c++ containers iterator unique-ptr

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

如何在C++ 11中实现make_unique函数?

我的编译器不支持make_unique.怎么写一个?

template< class T, class... Args > unique_ptr<T> make_unique( Args&&... args );
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr c++11 c++14

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

通过make_unique/make_shared调用initializer_list构造函数

我试图用来std::make_unique实现一个构造函数要接收的类std::initializer_list.这是一个最小的案例:

#include <string>
#include <vector>
#include <initializer_list>
#include <memory>

struct Foo {
    Foo(std::initializer_list<std::string> strings) : strings(strings) {}

    std::vector<std::string> strings;
};

int main(int, char**) {

    auto ptr = std::make_unique<Foo>({"Hello", "World"});

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以在Coliru上看到它没有构建:

main.cpp:14:56: error: no matching function for call to 'make_unique(<brace-enclosed initializer list>)'
     auto ptr = std::make_unique<Foo>({"Hello", "World"});
Run Code Online (Sandbox Code Playgroud)

那么,make_unique据说无法使用initializer_lists?GCC 4.9.1中有错误吗?或者我忽略了什么?

c++ initializer-list unique-ptr c++14

27
推荐指数
2
解决办法
9451
查看次数

如何让std :: make_unique成为我班级的朋友

我想声明std::make_unique函数是我班级的朋友.原因是我想声明我的构造函数protected并提供一种使用创建对象的替代方法unique_ptr.这是一个示例代码:

#include <memory>

template <typename T>
class A
{
public:
    // Somehow I want to declare make_unique as a friend
    friend std::unique_ptr<A<T>> std::make_unique<A<T>>();


    static std::unique_ptr<A> CreateA(T x)
    {
        //return std::unique_ptr<A>(new A(x)); // works
        return std::make_unique<A>(x);         // doesn't work
    }

protected:
    A(T x) { (void)x; }
};

int main()
{
    std::unique_ptr<A<int>> a = A<int>::CreateA(5);
    (void)a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在我收到此错误:

Start
In file included from prog.cc:1:
/usr/local/libcxx-head/include/c++/v1/memory:3152:32: error: calling a protected constructor of class 'A<int>'
return …
Run Code Online (Sandbox Code Playgroud)

c++ templates unique-ptr friend-function c++14

27
推荐指数
1
解决办法
4684
查看次数

如果需要存储删除器,unique_ptr怎么没有开销?

先来看看什么C++入门谈到unique_ptrshared_ptr:
$ 16.1.6.效率和灵活性

我们可以确定shared_ptr不将删除器作为直接成员,因为删除器的类型直到运行时才知道.

因为删除器的类型是a unique_ptr类型的一部分,所以删除器成员的类型在编译时是已知的.删除器可以直接存储在每个unique_ptr对象中.

所以似乎shared_ptr没有直接的删除成员,但unique_ptr确实如此.然而,另一个问题的最高投票回答说:

如果将deleter作为模板参数提供(如unique_ptr),则它是类型的一部分,您不需要在此类型的对象中存储任何其他内容.如果将deleteter作为构造函数的参数传递(如shared_ptr),则需要将其存储在对象中.这是额外灵活性的代价,因为您可以为相同类型的对象使用不同的删除器.

引用的两段完全相互矛盾,让我感到困惑.更重要的是,许多人说unique_ptr是零开销,因为它不需要将删除器存储为成员.但是,正如我们所知,unique_ptr有一个构造函数unique_ptr<obj,del> p(new obj,fcn),这意味着我们可以将删除函数传递给它,因此unique_ptr似乎已将删除函数存储为成员.真是一团糟!

c++ smart-pointers unique-ptr c++-standard-library c++11

27
推荐指数
3
解决办法
3889
查看次数

在地图中存储带自定义删除器的unique_ptr

为什么这不起作用?

#include <map>
#include <memory>

void deleter(int* i) {
    delete i;
}

std::map<int, std::unique_ptr<int, decltype(&deleter)>> m;

void foo(int* i) {
    m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);
}
Run Code Online (Sandbox Code Playgroud)

看看难以理解的编译错误https://godbolt.org/z/Uhp9NO.

In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/map:61:
In file included from /opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_map.h:63:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/tuple:1668:9: error: no matching constructor for initialization of 'std::unique_ptr<int, void (*)(int *)>'
        second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
        ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/tuple:1655:9: note: in instantiation of function template specialization 'std::pair<const int, std::unique_ptr<int, void (*)(int *)> >::pair<int &&, 0>' requested here
      : pair(__first, __second, …
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr

27
推荐指数
2
解决办法
1003
查看次数

unique_ptr线程安全吗?

unique_ptr线程安全吗?以下代码是否无法两次打印相同的数字?

#include <memory>
#include <string>
#include <thread>
#include <cstdio>

using namespace std;

int main()
{
    unique_ptr<int> work;

    thread t1([&] {
        while (true) {
            const unique_ptr<int> localWork = move(work);
            if (localWork)
                printf("thread1: %d\n", *localWork);
            this_thread::yield();
        }
    });

    thread t2([&] {
        while (true) {
            const unique_ptr<int> localWork = move(work);
            if (localWork)
                printf("thread2: %d\n", *localWork);
            this_thread::yield();
        }
    });

    for (int i = 0; ; i++) {
        work.reset(new int(i));

        while (work)
            this_thread::yield();
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ multithreading thread-safety unique-ptr c++11

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

std :: unique_ptr,deleters和Win32 API

在VC2012中,我想使用唯一指针和删除器在构造函数中创建一个互斥锁,这样我就不需要创建一个析构函数来调用CloseHandle.

我原以为这会起作用:

struct foo
{
    std::unique_ptr<HANDLE, BOOL(*)(HANDLE)> m_mutex;
    foo() : m_mutex(CreateMutex(NULL, FALSE, NULL), CloseHandle) {}
}
Run Code Online (Sandbox Code Playgroud)

但在编译时我收到一个错误:

error C2664: 'std::unique_ptr<_Ty,_Dx>::unique_ptr(void *,int 
(__cdecl *const &)(HANDLE)) throw()' : cannot convert parameter 1 from 
'HANDLE' to 'void *'
Run Code Online (Sandbox Code Playgroud)

当我修改构造函数时:

foo() : m_mutex((void*)CreateMutex(NULL, FALSE, 
    (name + " buffer mutex").c_str()), CloseHandle) {}
Run Code Online (Sandbox Code Playgroud)

我变得更加不寻常:

error C2664: 'std::unique_ptr<_Ty,_Dx>::unique_ptr(void *,
int (__cdecl *const &)(HANDLE)) throw()' : cannot convert 
parameter 1 from 'void *' to 'void *'
Run Code Online (Sandbox Code Playgroud)

我现在不知所措.HANDLE是void*的typedef:我需要了解一些转换魔法吗?

c++ winapi unique-ptr c++11

26
推荐指数
2
解决办法
6350
查看次数

使用std :: unordered_set的std :: unique_ptr

假设我有一组unique_ptr:

std::unordered_set <std::unique_ptr <MyClass>> my_set;
Run Code Online (Sandbox Code Playgroud)

我不确定检查集合中是否存在给定指针的安全方法是什么.这样做的正常方法可能是调用my_set.find (),但我作为参数传递什么?

我从外面得到的只是一个原始指针.所以我必须从指针创建另一个unique_ptr,将它传递给find()然后release()指针,否则对象将被破坏(两次).当然,这个过程可以在一个函数中完成,因此调用者可以传递原始指针并进行转换.

这种方法安全吗?有没有更好的方法来使用一组unique_ptr?

c++ stl unordered-set unique-ptr c++11

26
推荐指数
4
解决办法
6048
查看次数

Pimpl - 为什么可以在不完整的类型上调用make_unique

为什么make_unique调用编译?make_unqiue不要求其模板参数是完整类型吗?

struct F;
int main()
{
  std::make_unique<F>();
}

struct F {};
Run Code Online (Sandbox Code Playgroud)

从orignated问题我的"问题"与我PIMPL实现:

我确实理解为什么析构函数必须在用户声明并在实现类(PIMPL)的cpp文件中定义.

但是移动包含pimpl的类的构造函数仍会编译.

class Object
{};

class CachedObjectFactory
{
public:
  CachedObjectFactory();

  ~CachedObjectFactory();
  std::shared_ptr<Object> create(int id) const;

private:
  struct CacheImpl;
  std::unique_ptr<CacheImpl> pImpl;
};
Run Code Online (Sandbox Code Playgroud)

现在cpp文件:

// constructor with make_unique on incompete type ?
CachedObjectFactory::CachedObjectFactory()
  : pImpl(std::make_unique<CacheImpl>())
{}

struct CachedObjectFactory::CacheImpl
{
  std::map<int, std::shared_ptr<Object>> idToObjects;
};

//deferred destructor
CachedObjectFactory::~CachedObjectFactory() = default;
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么这个编译?为什么建筑和破坏之间存在差异?如果析构函数的实例化和default_deleter的实例化是一个问题,为什么make_unique的实例化不是问题?

c++ templates pimpl-idiom unique-ptr language-lawyer

26
推荐指数
2
解决办法
1134
查看次数