我正在使用 C++(C++11 也可以)开发一个属性系统,以便类可以向脚本系统提供数据。我想提供各种“类型”的属性,最简单的一种在内部保持其价值,如下所示:
// Simple Property
template<typename Value>
class Property {
public:
Value get() const;
void set(Value value);
private:
Value m_value;
}
在大多数情况下,这没关系,但有时,该值是计算出来的,或者由于其他原因必须在属性对象之外。对于这种情况,我想提供一个这样的模板:
// Complicated Property
template<
typename Value,
typename ValueOwner,
Value (ValueOwner::*Getter)(void) const,
void (ValueOwner::*Setter)(Value)
>
class Property {
// Stuff for calling the getter & setter
}
有什么方法可以让这两个模板共存而不重命名其中一个?我试过这个来专门化 Getter / Setter 模板:
// Complicated Property
// ...
// Simple Property
template<typename Value>
class Property<Value, void, nullptr, nullptr>;
但是编译器不喜欢这样并抱怨creating pointer to member function non-class type "const void"
. 呃,当然 void 没有成员函数。
然后我尝试用足够的参数声明模板,然后专门化上述模板,如下所示:
template<typename A, typename B, typename C, typename D>
class Property;
// Simple Property
// ...
// Complicated Property
// ...
但这也不起作用,因为 Getter / Setter 模板不期望类型名作为第三个和第四个参数,而是指向成员函数的指针。
下次尝试:
// Complicated Property
// ...
// Simple Property
template<typename Value>
class Property<
Value,
Property<Value>,
&Property<Value>::get,
&Property<Value>::set
>;
编译失败,因为编译器现在没有Property<Value>
模板参数中的模板。
好吧,也许这个:
// Complicated Property
// ...
template<typename Value>
struct PropertyDummy {
Value get() const;
void set(Value);
}
// Simple Property
template<typename Value>
class Property<
Value,
PropertyDummy<Value>,
&PropertyDummy<Value>::get,
&PropertyDummy<Value>::set
>;
这产生template argument involves template parameter(s)
了 getter 和 setter 模板参数。他们当然会。
无论如何,将模板重命名为对我有用的东西Property
就SimpleProperty
足够了。但我很好奇是否有解决方案,以便我可以同时编写
Property<int> simpleProperty;
Property<int, MyClass, &MyClass::get, &MyClass::set> complicatedProperty;
并让编译器弄清楚我的意思是哪个模板。