c++ - std::any 的存储对象类型的可能性

标签 c++ metaprogramming c++17 c++-standard-library

在 c++17 中我们有 std::any它将可变类型的对象存储在内存中。好的部分是我可以创建一个 std::any vector 来模拟任意类型对象的容器。

每当从容器中查询对象时,都会使用 std::any_cast调用时使用完全相同的类型 std::make_any创建任何对象。这是我如何实现这一目标的片段

#include <any>
#include <iostream>
#include <unordered_map>
#include <vector>
#include <set>

int main()
{
    /* create some objects */
    std::set<int> mySet = { 1, 2, 3 };
    std::vector<int> myVec = { 3, 4, 5 };
    std::unordered_map<int, std::vector<int>> myHash = { std::make_pair(1, myVec) };
    /* create any store */
    std::vector<std::any> anyStore;
    anyStore.push_back(std::make_any<decltype(mySet)>(mySet));
    anyStore.push_back(std::make_any<decltype(myVec)>(myVec));
    anyStore.push_back(std::make_any<decltype(myHash)>(myHash));
    /* get object back */
    auto newSet = std::any_cast<decltype(mySet)>(anyStore[0]);
    auto newVec = std::any_cast<decltype(myVec)>(anyStore[1]);
    auto newHash = std::any_cast<decltype(myHash)>(anyStore[2]);

    /* Question is can we store the decltype(mySet) in memory so that 
     * it can be read back while query from the vector to do any_cast?
     */

    return 0;
}

问题如下: 是否可以将 decltype(mySet) 存储为运行时变量,以便我们可以在 any_cast 中使用它来自动解析我们想要获取的类型?我知道你可能无法将类型存储在内存中,因为它是编译时变量,但是有没有解决方法,比如使用 std::type_indexstd::type_info实现目标?

编辑:
根据@KerrekSB 的要求。下面是使用 std::any 的动态大小容器创建具有动态属性的类的示例。

#include <any>
#include <iostream>
#include <unordered_map>
#include <vector>
#include <set>
#include <string>

class FooWithDynamic
{
public:
    FooWithDynamic() = default;

    template <class T>
    void RegisterProperty(const std::string &key, const T &obj)
    {
        m_store.emplace(key, std::make_any<T>(obj));
    }

    template <class T>
    T GetProperty(const std::string &key)
    {
        if (m_store.find(key) == m_store.end())
            throw;
        return std::any_cast<T>(m_store[key]);
    }
private:
    std::unordered_map<std::string, std::any> m_store;
};

int main()
{
    /* create some objects */
    FooWithDynamic foo;
    foo.RegisterProperty("mySet", std::set<int>{ 1, 2, 3 });
    foo.RegisterProperty("myVec", std::vector<int>{ 1, 2, 3 });
    foo.RegisterProperty("myHash", std::unordered_map<int, int>{ std::make_pair(1, 2) });
    /* query back object */
    auto mySet = foo.GetProperty<std::set<int>>("mySet");
    auto myVec = foo.GetProperty<std::vector<int>>("myVec");
    auto myHash = foo.GetProperty<std::unordered_map<int, int>>("myHash");
    return 0;
}

感谢大家让我知道这是不可能的,因为它与 C++ 的静态类型哲学形成对比。

最佳答案

Is it possible to store the decltype(mySet) as run time variable

没有。 C++ 是一种静态类型语言。无法在运行时确定类型。每个表达式的类型,例如将返回存储在 any 中的值的函数的返回值,必须在编译时已知。

这正是您在 any_cast 时必须明确提供类型的原因。

关于c++ - std::any 的存储对象类型的可能性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47705978/

相关文章:

c++ - 具有不同类型的两个参数的隐式模板类型推导

c++ - 模板函数可以推导出 lambda 的参数吗?

c++ - opencv brg 颜色直方图不起作用

c++ - iOS 上的 OpenCv 2.4.7 错误 background_segm.hpp #include <list> not found

c++ - 有没有一种聪明的方法来实现完全静态的观察者模式(在编译时)

c++ - 为什么不将类型名模板参数隐式识别为类型?

c++ - 创建可折叠模板参数包

c++ STL map copy 将 bool 值设置为 true

c++ - cmake编译组

php - 元编程到几种输出语言