我正在对算法实施优化。
优化包括在结构中值的值已知为唯一时立即停止搜索。为了明白这一点,想象一下我的结构就像一个数据库表,具有唯一值的字段将等同于"主键"在关系数据库中。
如果我知道该字段的值是唯一的,那么我想调度一个在找到第一次出现值时急切停止的实现。我在编译时通过设计知道这一点。
所以我想检测一个给定的字段值在编译时是唯一的。
我的功能如下:
template <class Storage, class Getter, class Value>
vector<MyStruct> select_records(Storage const & s, Getter g, Value const & v);
此功能将发送:
我怎样才能实现&#34;主键&#34;检测?约束:解决方案必须是非侵入式的。
答案 0 :(得分:2)
根据您提供的信息,无法在编译时执行您想要的操作。 Getter
只是一种类型,并且您说您无法单独按类型识别主键。这意味着您不会根据Getter
(类型)进行识别,而是基于g
,即运行时值。当然,没有编译时访问运行时值。
如果可能,您可以通过将g
转换为编译时信息来实现此目的,如下所示:
template <class Storage, class Value, Value Storage::*getter>
vector<MyStruct> select_records(Storage const & s, Value const & v);
然后将其专门化为getter
的已知值,这些值对应于主键。
当然,上面要求你明确指定所有模板参数(因为你要指定的那个,getter
,是最后一个),并且并不真正好玩,因为函数模板不能部分专业化。这里提供了一些更好的语法和专业化选项:
template <class Storage, class Value>
Selector<Storage, Value> record_selector(Storage const & s, Value const & v)
{
return Selector<Storage, Value>(s, v);
}
template <class Storage, class Value>
class Selector
{
Storage const & s;
Value const & v;
public:
Selector(Storage const & s, Value const & v) : s(s), v(v) {}
template <Value Storage::*getter>
vector<MyStruct> select()
{
return Select_Impl<Storage, Value, getter, IsPrimaryKey<Storage, Value, getter>::value>::call(s, v);
}
};
template <class Storage, class Value, Value Storage::*getter, bool primary>
struct Select_Impl
{
static vector<MyStruct> call(Storage const & s, Value const & v)
{
// Normal implementation.
}
};
template <class Storage, class Value, Value Storage::*getter>
struct Select_Impl<Storage, Value, getter, true>
{
static vector<MyStruct> call(Storage const & s, Value const & v)
{
// Optimised implementation
}
};
template <class Storage, class Value, Value Storage::*getter>
struct IsPrimaryKey
{
static const bool value = false;
};
// Specialise the above for each primary key with `value` set to `true`
// This should be possible, since you said you know the set of primary keys at compile-time
在代码中,您应该能够像这样使用它:
vector<MyStruct> res = record_selector(s, v).select<&SomeStorage::someMember>();