具有 ADL 支持的就地make_unique
In-place make_unique with ADL support
我正在努力更好地学习模板,所以我为就地unique_ptr
编写了一个小函数。这是我的代码:
#include <iostream>
#include <array>
#include <memory>
#include <functional>
struct A {
int a = 0;
double b = 0.0;
A() { std::cout << "c1n"; }
A(int a) : a(a) { std::cout << "c2n"; }
~A() { std::cout << "dn"; }
};
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;
添加到代码顶部时,代码编译时出错。发生这种情况似乎是因为编译器无法区分我的make_unique()
和库中指定的内容。我想它与此冲突:
template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args );
我想知道这是否是一种解决此问题的方法? 或者最简单的方法是将我的make_unique()
重命名为另一个函数?
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 );
与放置 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)...)
);
};
};
这需要比标准unique_ptr
多 0 个内存 - 删除程序是无状态的。 它甚至在不同的unique_ptr
类型之间很常见。
相关文章:
- 为什么 std::unique 不调用 std::sort?
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- make 命令如何避免重新编译未更改的源文件?
- MAKE:找不到包含的用户定义的头文件?
- 'make check' GLIBC 运行时的链接问题
- 生成"unique"矩阵
- Qt5 [make -snap] 无法正确编译:进程"/usr/bin/snap"代码 1 退出
- mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库
- 我对 std::unique(算法)C++有问题
- make 命令创建 .file,但不创建应用程序文件
- 如何摆脱导入的 make 项目中的 Eclipse 索引器"Type std::... could not be resolved"错误
- Qt Creator 在执行步骤 "make" 时出现编译错误,-fno-stack-limit
- 如何使用MySQL Connector and Make设置C++项目
- 使用 make 将对象文件放在特定目录中
- 我是 C++ 的新手,我试图调用 make 一个以 2 个类作为其参数的类构造函数
- "Make"失败并出现 Clang 错误 - 如何从 Clang 获得错误?
- 防止 GNU Make 在每次构建时生成 protobuf 代码
- Make zmqpp::socket::connect a std::future
- 链接从命令行转换为Make的库