很抱歉描述比较长,我尽可能地缩减了例子以说明我的问题。我有以下代码:
#include <concepts>
#include <type_traits>
template<typename T>
concept NumericPropertyValue = (std::is_integral_v<T> && !std::is_same_v<T, bool>) || std::is_floating_point_v<T>;
template<NumericPropertyValue T>
class Property
{
public:
Property(const char* name, T minValue, T maxValue, T defaultValue)
: _name(name)
, _minValue(minValue)
, _maxValue(maxValue)
, _value(defaultValue)
{
}
T operator=(T value)
{
// check the value, ...
return _value;
}
operator T() const
{
return _value;
}
// some other utility functions
private:
const char* const _name;
const T _minValue;
const T _maxValue;
T _value;
};
struct SomeType
{
SomeType()
: p1("p1Name", -100, 100, 0)
, p2("p2Name", 0.0, 1.0, 0.0)
{
}
Property<int> p1;
Property<double> p2;
};
int main()
{
SomeType test1;
SomeType test2;
return 0;
}
正如您所看到的,所有SomeType
实例的Property
成员都具有相同的参数,这意味着不止一个实例:
const char* const _name;
const T _minValue;
const T _maxValue;
只是浪费内存,它们可以共享。解决此问题的一种选项是使用 PropertyMetadata
类来存储此信息,例如:
template<NumericPropertyValue T>
struct PropertyMetadata
{
const char* const _name;
const T _minValue;
const T _maxValue;
};
template<NumericPropertyValue T>
class Property
{
public:
Property(const PropertyMetadata<T>& metadata, T defaultValue)
: _metadata(metadata)
, _value(defaultValue)
{
}
T operator=(T value)
{
// check the value, ...
return _value;
}
operator T() const
{
return _value;
}
private:
const PropertyMetadata<T>& _metadata;
T _value;
};
PropertyMetadata<int> p1Metadata("p1Name", -100, 100);
PropertyMetadata<double> p2Metadata("p2Name", 0.0, 1.0);
struct SomeType
{
SomeType()
: p1(p1Metadata, 0)
, p2(p2Metadata, 0.0)
{
}
Property<int> p1;
Property<double> p2;
};
第二种方法可行且不会浪费空间,但与第一种方法相比非常不方便。
是否可以在构造函数初始化列表或其他方式中直接生成具有静态存储的对象,或者有没有其他方法可以在不声明静态变量的情况下在所有
SomeType
实例之间共享这些元数据?注意:在这个简单的示例中,
PropertyMetadata
只有几个参数,可能看起来并不会浪费太多内存,但实际上它有更多成员,并且其中一些成员使用动态分配。