2017-08-25 75 views
0

我有下面的类:自定义迭代器指向一个临时对象(延迟加载)

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类这样的方式,这将是迭代像在过去的代码片段?

+0

是的,这是可能的,但你必须真正创建自己的自定义迭代器,它是一个实际的文件,而不是一个路径。也许你应该仔细查看一下设计,以获得某种“ReaderContainer”,其中包含(未打开的)文件集合,并且取消引用自定义迭代器打开该文件(如果尚未打开)? –

+0

创建某种简单的懒惰资源类将是最简单的。然后你可以很容易地创建一个容器('std :: vector '等),或者用它来构建一个自定义的迭代器/容器来满足你的需求。一次解决一个问题。 –

回答

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 
+0

这里的想法是它必须以我提到的方式迭代。这是一种解决方案,但与我需要实施的方式不兼容。 –

+0

你真的需要确切的语法吗?你可以执行'for(auto&file:container)imshow(file.get());'或者juse改变'imshow'接受'LazyInputFile'然后'for(auto&file:container)imshow(file);'为什么不能使用普通容器?就像我说的,它有两个不同的问题。如果你真的想要,你可以创建一个迭代器适配器,让运算符'*'为你执行'.get()',或者创建一个隐式的转换运算符。 –