具有 ADL 支持的就地 make_unique

阿夫申

我正在尝试更好地学习模板,所以我为in-placeunique_ptr编写了一个小函数这是我的代码:

#include <iostream>
#include <array>
#include <memory>
#include <functional>

struct A {
    int a = 0;
    double b = 0.0;
    A() { std::cout << "c1\n"; }
    A(int a) : a(a) { std::cout << "c2\n"; }
    ~A() { std::cout << "d\n"; }
};

template<typename T, typename... Args>
auto make_unique(void *p, Args&&... args) {
    return std::unique_ptr<T, std::function<void(T*)>>(
                     new(p) T(std::forward<Args>(args)...), 
                     [](T* ptr) { ptr->~T(); });
};

int main() {
    std::array<char,50> buf1;
    std::array<char,50> buf2;

    auto o1 = make_unique<A>(buf1.data());
    auto o2 = make_unique<A>(buf2.data(), 3);
}

这段代码按我的预期工作,并在对象生命周期以就地方式结束时调用构造函数/析构函数

但这是我的问题。我喜欢将它用作 ADL(依赖于参数的查找),但是当我添加using std::make_unique;到代码顶部时,代码编译时出错。发生这种情况似乎是因为编译器无法区分 mymake_unique()和库中指定的内容。我想它与这个冲突:

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

我想知道这是否是一种解决方法?或者最简单的方法是将 my 重命名make_unique()为另一个函数?

Yakk - Adam Nevraumont

如果其参数可用于创建对象,则 std make unique 不会以 SFINAE/重载友好方式进行测试。即使这样做了,您的计划也会很糟糕,因为新放置和非放置新不应该依赖于 delecate 过载选择。它们是非常不同的操作。

所以有一些改进:

template<class T>
auto placement_unique(void *p) {
  return [p](auto&&...args) {
    return std::unique_ptr<T, void(*)(T*)>(
                 ::new(p) T(decltype(args)(args)...), 
                 +[](T* ptr) { ptr->~T(); }
    );
  };
};

用途是:

auto pa = placement_unique<A>(ptr)( 7 );

与placement new 一样,指针和对象参数是分开的。

这可以进一步改进:

struct destroy_it {
  template<class T>
  void operator()(T* t)const { if (t) t->~T(); }
};

template<class T>
using unique_placed_ptr = std::unique_ptr<T, destroy_it>;
template<class T>
auto placement_unique(void *p) {
  return [p](auto&&...args) {
    return unique_placed_ptr<T>(
                 ::new(p) T(decltype(args)(args)...)
    );
  };
};

这需要比标准多 0 的内存unique_ptr——删除器是无状态的。它甚至在不同unique_ptr类型之间很常见

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

带有std :: make_unique的push_back或emplace_back

来自分类Dev

无法访问在类中为make_unique声明的私有成员

来自分类Dev

有没有办法让“make_unique<T[]>”可以将参数转发给T的构造函数?

来自分类Dev

为什么make_unique可以使用std :: bind作为参数的构造函数有额外的动作?

来自分类Dev

从Qt 5.6切换到Qt 5.7-“命名空间std中没有成员'make_unique'”

来自分类Dev

在派生类上使用带有自定义删除程序的std :: make_unique吗?

来自分类Dev

ADL未使用具有模板参数列表的后缀表达式

来自分类Dev

如何在允许ADL等的同时调用具有相同名称的其他函数

来自分类Dev

是否可以具有只能由ADL找到的非朋友功能?

来自分类Dev

如何在允许ADL等的同时调用具有相同名称的其他函数

来自分类Dev

具有支持库的PreferenceFragment

来自分类Dev

具有 redis 支持的 Scalacache

来自分类Dev

C ++和Lua Api,具有工厂功能的就地分配

来自分类Dev

具有返回值的DataFrame就地修改

来自分类Dev

具有就地值定义的javascript对象文字

来自分类Dev

具有重叠切片的 NumPy 就地操作

来自分类Dev

智能替换'new []'到make_unique

来自分类Dev

std :: make_unique对SFINAE友好吗?

来自分类Dev

llvm :: make_unique的用途是什么?

来自分类Dev

std :: make_unique <std :: thread>与lambda

来自分类Dev

make_unique提供错误2248

来自分类Dev

GDI +对象的std :: make_unique

来自分类Dev

使用std :: make_unique <>进行分配

来自分类Dev

'make_unique'不是'std'的成员

来自分类Dev

std :: make_unique与新的位置

来自分类Dev

unique_ptr,make_unique和多态

来自分类Dev

具有集群支持的Spring Data Redis

来自分类Dev

Task.Run具有取消支持

来自分类Dev

具有恢复支持的Indy Http Server

Related 相关文章

热门标签

归档