繁体   English   中英

存储和重新使用decltype值?

[英]storing and re-using decltype value?

如果我有一个模板:

template <class T>
struct Item
{
  T _value;
};

然后我可以这样做:

// ...
Item<int> x = { 42 }; // declared as an int

// ...
decltype(x._value) y = 20; // 'y' is also an int

但是可以将decltype存储到变量中以便以后使用吗?

为什么?
我想将项的值存储为指针。

std::vector<Item*>但是因为它们是模板我必须将它们存储为void指针:

std::vector<void*> is;
is.push_back(new Item<int>());
is.push_back(new Item<double>());
is.push_back(new Item<float>());

这一切都很好,但是当需要删除指针时,我需要将我的void*重新转换为正确的类型(因此调用析构函数):

delete (Item<int>*)is[0];

如果我知道类型,我可以这样做:

delete (Item<decltype(whatever)>*)is[0];

因此我需要存储decltype的原因。

我希望这是有道理的。

decltype是一种语言功能,允许您在编译时检索类型。 您似乎希望“存储”该类型,以便您可以在运行时正确delete在动态存储上分配的对象。 假设是这种情况, decltype在这里没有帮助。

你有各种选择:

  1. 使用某种形式的类型擦除工具,如Boost.VariantBoost.Any ,如Baum mit Augen在评论中所建议的那样。

  2. 使您的对象成为多态层次结构的一部分并使用智能指针:

     struct ItemBase { virtual ~ItemBase() { } }; template <class T> struct Item : ItemBase { T _value; }; int main() { std::vector<std::unique_ptr<ItemBase>> items; items.emplace_back(std::make_unique<Item<int>>()); items.emplace_back(std::make_unique<Item<float>>()); items.emplace_back(std::make_unique<Item<double>>()); } 

如果问题只是删除它们,您可以将unique_ptr与自定义删除器而不是裸指针一起使用。
您无需修改​​层次结构即可执行此操作。
举个例子:

std::vector<std::unique_ptr<void, void(*)(void*)>> is;
is.push_back(std::unique_ptr<void, void(*)(void*)>{new Item<int>(), [](void *ptr) { delete static_cast<Item<int>*>(ptr); }}); 

如果使用emplace_back而不是push_back更好:

std::vector<std::unique_ptr<void, void(*)(void*)>> is;
is.emplace_back(new Item<int>(), [](void *ptr) { delete static_cast<Item<int>*>(ptr); }); 

它遵循基于OP代码的最小工作示例:

#include<vector>
#include<memory>

template<typename>
struct Item {};

int main() {
    using Deleter = void(*)(void*);
    std::vector<std::unique_ptr<void, Deleter>> is;
    is.emplace_back(new Item<int>(), [](void *ptr) { delete static_cast<Item<int>*>(ptr); }); 
    is.emplace_back(new Item<double>(), [](void *ptr) { delete static_cast<Item<double>*>(ptr); }); 
    is.emplace_back(new Item<float>(), [](void *ptr) { delete static_cast<Item<float>*>(ptr); }); 
}

您可以存储删除者

所以使用std::shared_ptr ,它变为:

std::vector<std::shared_ptr<void>> items;

// The simplest
items.push_back(std::make_shared<Item<int>>(/*args...*/));

// Explicitly specify the (default) deleter
items.push_back(std::shared_ptr<void>{new Item<double>(/*args...*/),
                                      std::default_delete<Item<double>>{}});

// Explicitly specify the (default) allocator
items.push_back(
    std::allocate_shared<Item<float>>(std::allocator<Item<float>>{} /*, args...*/);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM