自定义迭代器指向临时对象(延迟加载)

时间:2017-08-25 08:48:38

标签: c++ iterator lazy-loading

我有以下课程:

template <class T>
class IReader
{
    using const_iterator = std::vector<filesystem::Path>::const_iterator;

public:
    virtual ~IReader() = default;

    virtual T read(const_iterator path) const = 0;

    virtual const_iterator begin() const = 0;
    virtual const_iterator end() const = 0;

    virtual size_t size() const = 0;
};

这是一个应该提供延迟加载文件的接口。此类的实现将获得可读路径列表和按需读取文件。本课程的示例用法如下:

Reader reader; // Reader implements IReader
for(auto path : reader)
{
    auto decodedFile = reader.read(path);
    imshow(decodedFile);
}

这看起来有点奇怪 - 作为这个类的用户,我不需要知道它存储的文件名。如果我能按如下方式使用这个类会更方便:

Reader reader; // Reader implements IReader
for(auto file : reader)
{
    imshow(*file);
}

在C ++中是否可以设计IReader类,使其像上一个代码片段一样可迭代?

1 个答案:

答案 0 :(得分:2)

创建某种简单的惰性资源类最简单。然后,您可以轻松地创建容器(std::vector<LazyFile>等),然后使用它来构建自定义迭代器/容器以满足您的需求。一次解决一个问题。

template<class T> class LazyFileInput
{
public:
    LazyInputFile(const std::string &path)
        : path(path), data(), loaded(false);

    const T &get()
    {
        std::unique_lock<std::mutex> lock(mutex);
        if (!loaded) load_file();
        return data;
    }
private:
    std::string path;
    T data;
    std::mutex mutex;
    bool loaded;

    void load_file()
    {
        // TODO: Implement this however you want to load your T data.
        std::ifstream fs(path);
        fs >> data;
        loaded = true;
    }
};

// Is a custom iterator even needed at this point? Certainly a seperate problem however.
std::vector<LazyFileInput> files;
std::unordered_map<std::string, LazyInputFile> images; // image name -> image