c++ - 如何按类型(不是值)添加使用指向成员值的指针作为模板参数

标签 c++ member-pointers

我的情况:

我经常需要一个结构 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_setset

如果您要返回对底层 vector 中可变对象的引用,那么您也可以简单地使用带有谓词的 std::find_if 来查找它们。

关于c++ - 如何按类型(不是值)添加使用指向成员值的指针作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39334780/

相关文章:

二值图像的泛洪填充C++算法

带变量的 C++ 幂函数

c++ - 引用创建错误的 fstream 对象

c++ - 奇怪的语法:范围运算符 (::) 后的星号?

c++ - 成员函数指针

c++ - 与具有浮点值的 0.0 进行比较

Windows 和 Linux 之间的 C++ 可移植性

c++ - 将指针传递给成员函数

c++ - 比较成员指针

c++ - 我可以将成员数据指针分配给派生类型吗?