Using the Proxy pattern with C++ iterators
- by Billy ONeal
Hello everyone :)
I've got a moderately complex iterator written which wraps the FindXFile apis on Win32. (See previous question) In order to avoid the overhead of constructing an object that essentially duplicates the work of the WIN32_FIND_DATAW structure, I have a proxy object which simply acts as a sort of const reference to the single WIN32_FIND_DATAW which is declared inside the noncopyable innards of the iterator. This is great because
Clients do not pay for construction of irrelevant information they will probably not use (most of the time people are only interested in file names), and
Clients can get at all the information provided by the FindXFile APIs if they need or want this information.
This becomes an issue though because there is only ever a single copy of the object's actual data. Therefore, when the iterator is incrememnted, all of the proxies are invalidated (set to whatever the next file pointed to by the iterator is).
I'm concerned if this is a major problem, because I can think of a case where the proxy object would not behave as somebody would expect:
std::vector<MyIterator::value_type> files;
std::copy(MyIterator("Hello"), MyIterator(), std::back_inserter(files));
because the vector contains nothing but a bunch of invalid proxies at that point. Instead, clients need to do something like:
std::vector<std::wstring> filesToSearch;
std::transform(
DirectoryIterator<FilesOnly>(L"C:\\Windows\\*"),
DirectoryIterator<FilesOnly>(),
std::back_inserter(filesToSearch),
std::mem_fun_ref(&DirectoryIterator<FilesOnly>::value_type::GetFullFileName)
);
Seeing this, I can see why somebody might dislike what the standard library designers did with std::vector<bool>. I'm still wondering though: is this a reasonable trade off in order to achieve (1) and (2) above? If not, is there any way to still achieve (1) and (2) without the proxy?