【问题标题】:Non-Static member variables creation like static singleton creation in C++非静态成员变量的创建,如 C++ 中的静态单例创建
【发布时间】:2015-04-12 17:21:39
【问题描述】:

首先,我真的很喜欢单例的延迟初始化模式。我通过以下方式使用它来获取具有不同值类型的不同类型的数据(示例已简化):

class A
{
    template<typename T>
    const T& getData() const
    {
        static T data;
        return data;
    }
}

我知道data 变量没有连接到该类的任何实例,并且在程序结束之前它一直存在。

但我现在想要的是,A 类的每个实例都应该以非静态方式保存变量,并且仍然应该具有调用 .getData&lt;bool&gt;() 或任何其他数据类型的灵活性,而无需在类定义中指定每种可能的数据类型。

这可能吗?我还没有想出实现它的想法。

我想到了一个容器,比如:

template<A*, typename T>
class DataContainer
{
    T data;
}

这样可以将代码扩展为:

class A
{
    template<typename T>
    const T& getData() const
    {
        static DataContainer<this, T> container;
        return container.data;
    }
}

但这不会编译。

你们中有人知道如何实现吗?

【问题讨论】:

    标签: c++ templates static non-static class-members


    【解决方案1】:

    这是一个想法,使用 Boost.any:

    #include <typeinfo>
    #include <type_index>
    #include <unordered_map>
    #include <boost/any.hpp>
    
    struct ThingGetter
    {
        template <typename T>
        T & get()
        {
            auto key = std::type_index(typeid(T));
            auto it = things.find(key);
    
            if (it == things.end())
            {
                it = things.emplace(key, boost::any(T())).first;
            }
    
            return boost::any_cast<T&>(*it);
        }
    
        std::unordered_map<std::type_index, boost::any> things;
    };
    

    这个简单的版本假定每种类型都可以进行值初始化,并在不存在所请求类型的条目时创建一个值初始化值。替代实现可以返回一个可能为 null 的指针并具有单独的插入接口。

    用法:

    ThingGetter mythings;
    
    mythings.get<bool>() = true;
    mythings.get<double>() = 1.5;
    return mythings.get<int>();
    

    【讨论】:

      猜你喜欢
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      相关资源
      最近更新 更多