2017-08-25 72 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()',或者創建一個隱式的轉換運算符。 –