我的情况:
我经常需要一个结构 vector ,其中一个字段可以被认为是键或 ID,而不是将它昂贵地存储在 map 中(内存使用在这个应用程序中非常重要)我想将它存储在一个平面 vector ,但呈现一个类似 map 的界面,用于按键查找元素。
我对这个问题的第一个解决方案:
template <class T, class Key, class KeyFn>
class TKeyedVector : public std::vector<T>
{
public:
const_iterator find(const Key& key) const {return std::find_if(begin(), end(), [&](const T& entry) {return keyFn(entry)==key; }); }
KeyFn keyFn;
};
struct KeyedDataEntry
{
std::string key;
int value;
struct KeyExtractor {
const std::string& operator()(const KeyedDataEntry& e) const {return e.key; };
};
};
using KeyedDataArray = TKeyedVector<KeyedDataEntry, std::string, KeyedDataEntry::KeyExtractor>;
现在一切正常,但我希望能够通过使用指向嵌入到类型中的成员变量的指针来消除对 KeyExtractor
类型的需要:
template <class T, class Key, Key T::* keyFn>
class TKeyedVector : public std::vector<T>
{
public:
const_iterator find(const Key& key) const {return std::find_if(begin(), end(), [&](const T& entry) {return keyFn(entry)==key; }); }
};
using KeyedDataArray = TKeyedVector<KeyedDataEntry, std::string, &KeyedDataEntry::key>;
但是我无法让它工作。我一直在查看 std::mem_fn
的实现以寻找线索,但我不知道该怎么做。我得到的错误是这样的:
warning C4353: nonstandard extension used: constant 0 as function expression. Use '__noop' function intrinsic instead
有什么线索吗?
编辑:样本版本在 http://ideone.com/Qu6TEy
最佳答案
这是工作解决方案的开始。您不需要特殊的提取器对象。
请注意,我已经封装了 vector 。假以时日,您会后悔没有这样做。
#include <vector>
#include <string>
template <class T, class Key, const Key& (T::*Extractor)() const>
class TKeyedVector
{
using storage = std::vector<T>;
using const_iterator = typename storage::const_iterator;
public:
decltype(auto) begin() const
{
return storage_.begin();
}
decltype(auto) end() const
{
return storage_.end();
}
const_iterator find(const Key& key) const
{
return std::find_if(begin(),
end(),
[&](const T& entry)
{
return entry.*Extractor() == key;
});
}
storage storage_;
};
struct KeyedDataEntry
{
std::string key;
int value;
const std::string& get_key() const { return key; }
};
int main()
{
TKeyedVector<KeyedDataEntry, std::string, &KeyedDataEntry::get_key> mymap;
}
但是你的这个想法有问题。
为了使这个结构成为一个映射,键必须是不可变的。这主张只返回不可变对象(immutable对象)。这然后立即争论是否简单地使用 unordered_set
或 set
。
如果您要返回对底层 vector 中可变对象的引用,那么您也可以简单地使用带有谓词的 std::find_if
来查找它们。
关于c++ - 如何按类型(不是值)添加使用指向成员值的指针作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39334780/