提问人:Konvt 提问时间:9/12/2023 最后编辑:Konvt 更新时间:9/13/2023 访问量:65
如何修复我的“Any”类代码以正确输出数据?
How do I fix my `Any` class code to output data correctly?
问:
我正在尝试模拟,我的想法是使用基类指针指向不同类型的模板派生类,以实现存储不同类型数据的功能,例如;因此,我编写了以下代码:std::any
std::any
class Any {
TypeBase *_ptr;
public:
Any(): _ptr(nullptr) {}
Any(const Any &other): Any() { _ptr = other._ptr->copy(); }
Any(Any&& _other): Any() {
_ptr = _other._ptr;
_other._ptr = nullptr;
}
template<typename T> Any(T&& _data): Any() {
/*
* this function attempts to capture rvalue param
*/
_ptr = new Container<T>(std::forward<T>(_data));
}
~Any() { delete _ptr; }
template<typename T> T& data_cast() const {
if (_ptr == nullptr)
throw std::runtime_error("Container empty");
return static_cast<Container<T>*>(_ptr)->data;
}
};
这些工具包类是:
struct TypeBase {
virtual ~TypeBase() {}
virtual TypeBase* copy() = 0;
};
template<typename T> struct Container: public TypeBase {
T data; // those datas will store here
Container() = delete;
template<typename U> Container(U&& _data): data(std::forward<U>(_data)) {}
virtual ~Container() {}
virtual TypeBase* copy() override { return (new Container<T>(data)); }
};
我的问题是,当我使用这样的代码时,生成的数据不会存储在:Container
#include <stdexcept>
// paste the definition given above
int main()
{
double y = 13.32;
Any a = y;
std::cout << "The data of 'a' is: " << a.data_cast<double>() << std::endl;
/* it doesn't work here, only outputs some wrong number */
return 0;
}
这是我的理解:编译器使用 隐式为我构造一个“Any”对象,然后调用复制构造函数来初始化 .y
a
我期望的是“Any”会接受左值和右值数据以减少复制开销,但显然我编写它的方式有问题,我没有意识到。
我尝试使用调试器来跟踪进程,发现函数调用进程完全符合我的预期。即使我可以看到指针是有效的,输出仍然很奇怪:.a
The data of a is: 3.10818e-317
我很难找到问题的根源,所以我希望有人指导我,或者也许我只是写了错误的代码,有人可以指出来。
答:
5赞
Miles Budnek
9/12/2023
#1
您正在构造一个,但后来将指向它的指针投射到 .Container<double&>
Container<double>*
将左值传递给转发引用时,模板参数将推导出为引用类型。也就是说,在
template<typename T> Any(T&& _data): Any() {
_ptr = new Container<T>(std::forward<T>(_data));
}
当你传递左值时,被推导出为 。这样,type 是 ,它折叠为 。如果是,那么将是一个 ,它不能绑定到左值。y
T
double&
_data
double& &&
double&
T
double
_data
double&&
解决方案非常简单:只需应用:std::remove_reference_t
template <typename T>
Any(T&& data) : Any() {
using DataT = std::remove_reference_t<T>;
_ptr = new Container<DataT>(std::forward<T>(data));
}
评论
toolkits
toolkits
TypeBase
Container
std::any
std::optional