前几天学了replacement new写的小玩意
cpp
#include <iostream>
#include <functional>
#include <string>
// 可能因为const char*类型的缘故
// 用const ArgsT&&...会报错
// 测试用类
struct Test
{
Test()
{
std::cout << "constructed" << std::endl;
};
~Test()
{
std::cout << "destructed" << std::endl;
};
};
// 析构器
template <typename T = char[]>
struct Destructor
{
void operator()(void *ptr)
{
T *obj = (T *)ptr;
// 调用析构函数
obj->~T();
};
};
// 基础类型没有析构函数
#define BASE_TYPE(type) \
template <> \
struct Destructor<type> \
{ \
void operator()(void *) {} \
};
BASE_TYPE(char[]);
BASE_TYPE(int);
//构造器
template <typename T>
struct Constructor
{
template <typename... ArgsT>
void operator()(void *ptr, ArgsT... args)
{
T *obj = (T *)ptr;
// replacement new
new (obj) T(std::forward<ArgsT>(args)...);
};
};
// 变体类
template <std::size_t size>
struct Variant
{
char memory[size] = {};
std::function<void(void *)> destructor = Destructor<>();
// 调用对象的析构函数
~Variant()
{
destructor(memory);
destructor = Destructor<>();
}
// 构造对象
template <typename NewT, typename... ArgsT>
void construct(ArgsT... args)
{
destructor(memory);
destructor = Destructor<NewT>();
Constructor<NewT> c;
c(memory, std::forward<ArgsT>(args)...);
}
// 获取对象
template <typename T>
T &get()
{
T *obj = (T *)memory;
return *obj;
}
template <typename T>
const T &get() const
{
const T *obj = (const T *)memory;
return *obj;
}
};
int main(int argc, char *argv[])
{
// 测试
/*Destructor<Test> d;
Test t;
d(&t);
Constructor<Test> c;
c(&t);*/
// 使用例
Variant<32> v;
v.construct<Test>();
v.construct<std::string, std::string>("aaa");
std::cout << v.get<std::string>() << std::endl;
v.construct<int, int>(666);
std::cout << v.get<int>() << std::endl;
return 0;
}