No, the signature of map<>::find
requires you pass in the key type.
There is, however, a relatively simple workaround. Use boost::optional
or std::tr2::optional
(from C++1y) to store your non-key data.
struct MetadataThingy {
void* pBlah;
optional<rest_of_stuff> rest;
static MetadataThingy searcher( void* );
MetadataThingy(...);
};
then call MeatadataThingy::searcher
to generate your key value.
Another approach would be to store smart (unique probably) pointers to sub-interfaces, each of which has a "get full data" method. Then, when you want to do a search, create a stub sub-interface that returns nullptr
on "get full data".
struct MetadataFull;
struct MetadataRoot {
virtual MetadataFull* get() = 0;
virtual MetadataFull const* get() const = 0;
virtual ~MetadataRoot() {}
};
template<typename T>
struct MetadataFinal: virtual MetadataRoot {
static_assert( std::is_base_of< T, MetadataFinal<T> >::value, "CRTP failure" );
virtual MetadataFull* get() { return static_cast<T*>(this); }
virtual MetadataFull const* get() const { return static_cast<T const*>(this); }
};
struct MetadataStub: virtual MetadataRoot {
virtual MetadataFull* get() { return nullptr; }
virtual MetadataFull const* get() const { return nullptr; }
};
struct MetaDataA: virtual MetaDataRoot {
void* pBlah;
};
struct MetaDataFull: MetaDataA, MetadataFinal<MetaDataFull> {
// unsorted data
};
struct MetaDataAStub: MetaDataA, MetaDataStub {};
now, this can be done with virtual
functions but not virtual
inheritance with a bit of finagling if you really need it.