#include <set>
#include <map>
#include <iostream>
#include <typeinfo>
//// This is a SFINAE context enabler. If T is defined R is returned
template<class T, class R=void> struct enable_if_type
{
typedef R type;
};
//// Default case is undefined as you want to get an error if you try to get a key_type from something that has none
template<class T, class Enable=void> struct key_type_of;
//// If T::key_type is a valid expression, extract it
template<class T>
struct key_type_of< T
, typename enable_if_type< typename T::key_type>::type
>
{
typedef typename T::key_type type;
};
int main()
{
typedef key_type_of< std::set<int> >::type skey;
typedef key_type_of< std::map<std::string,std::string*> >::type mkey;
std::cout << typeid(skey).name() << "\n";
std::cout << typeid(mkey).name() << "\n";
}
I2luY2x1ZGUgPHNldD4KI2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CgogICAgLy8vLyBUaGlzIGlzIGEgU0ZJTkFFIGNvbnRleHQgZW5hYmxlci4gSWYgVCBpcyBkZWZpbmVkIFIgaXMgcmV0dXJuZWQKICAgIHRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFI9dm9pZD4gc3RydWN0IGVuYWJsZV9pZl90eXBlCiAgICB7CiAgICAgICB0eXBlZGVmIFIgdHlwZTsKICAgIH07CgogICAgLy8vLyBEZWZhdWx0IGNhc2UgaXMgdW5kZWZpbmVkIGFzIHlvdSB3YW50IHRvIGdldCBhbiBlcnJvciBpZiB5b3UgdHJ5IHRvIGdldCBhIGtleV90eXBlIGZyb20gc29tZXRoaW5nIHRoYXQgaGFzIG5vbmUKICAgIHRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIEVuYWJsZT12b2lkPiBzdHJ1Y3Qga2V5X3R5cGVfb2Y7CgoKICAgIC8vLy8gSWYgVDo6a2V5X3R5cGUgaXMgYSB2YWxpZCBleHByZXNzaW9uLCBleHRyYWN0IGl0CiAgICB0ZW1wbGF0ZTxjbGFzcyBUPgogICAgc3RydWN0IGtleV90eXBlX29mPCBUCiAgICAgICAgICAgICAgICAgICAgICAsIHR5cGVuYW1lIGVuYWJsZV9pZl90eXBlPCB0eXBlbmFtZSBUOjprZXlfdHlwZT46OnR5cGUKICAgICAgICAgICAgICAgICAgICAgID4KICAgIHsKICAgICAgdHlwZWRlZiB0eXBlbmFtZSBUOjprZXlfdHlwZSB0eXBlOwogICAgfTsKCmludCBtYWluKCkKewogIHR5cGVkZWYga2V5X3R5cGVfb2Y8IHN0ZDo6c2V0PGludD4gPjo6dHlwZSBza2V5OwogIHR5cGVkZWYga2V5X3R5cGVfb2Y8IHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLHN0ZDo6c3RyaW5nKj4gPjo6dHlwZSBta2V5OwoKICBzdGQ6OmNvdXQgPDwgdHlwZWlkKHNrZXkpLm5hbWUoKSA8PCAiXG4iOwogIHN0ZDo6Y291dCA8PCB0eXBlaWQobWtleSkubmFtZSgpIDw8ICJcbiI7Cgp9