非静态成员变量的创建类似于 C++ 中的静态单例创建
Non-Static member variables creation like static singleton creation in C++
首先,我非常喜欢单例的惰性初始化模式。我通过以下方式使用它来获取具有不同值类型的不同类型的数据(示例已简化):
class A
{
template<typename T>
const T& getData() const
{
static T data;
return data;
}
}
我知道 data
变量没有连接到 class 的任何实例,并且它存在直到程序结束。
但我现在想要的是 class A 的每个实例都应该以非静态方式保存变量,并且仍然应该可以灵活地调用 .getData<bool>()
或任何其他数据类型,无需在 class 定义中指定每种可能的数据类型。
这可能吗?我还没有想出实施的想法。
我想到了像这样的容器:
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;
}
}
但是编译不了。
你们中有人知道如何实现吗?
这是一个想法,使用 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;
};
这个简单版本假定每个类型都可以进行值初始化,并在不存在所请求类型的条目时创建一个值初始化值。替代实现可以 return 一个可能为 null 并具有单独插入接口的指针。
用法:
ThingGetter mythings;
mythings.get<bool>() = true;
mythings.get<double>() = 1.5;
return mythings.get<int>();
首先,我非常喜欢单例的惰性初始化模式。我通过以下方式使用它来获取具有不同值类型的不同类型的数据(示例已简化):
class A
{
template<typename T>
const T& getData() const
{
static T data;
return data;
}
}
我知道 data
变量没有连接到 class 的任何实例,并且它存在直到程序结束。
但我现在想要的是 class A 的每个实例都应该以非静态方式保存变量,并且仍然应该可以灵活地调用 .getData<bool>()
或任何其他数据类型,无需在 class 定义中指定每种可能的数据类型。
这可能吗?我还没有想出实施的想法。
我想到了像这样的容器:
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;
}
}
但是编译不了。
你们中有人知道如何实现吗?
这是一个想法,使用 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;
};
这个简单版本假定每个类型都可以进行值初始化,并在不存在所请求类型的条目时创建一个值初始化值。替代实现可以 return 一个可能为 null 并具有单独插入接口的指针。
用法:
ThingGetter mythings;
mythings.get<bool>() = true;
mythings.get<double>() = 1.5;
return mythings.get<int>();