#include <iostream>
#include <type_traits>
#include <vector>
#include <set>
template<typename, typename T>
struct has_insert_method
{
static_assert(std::integral_constant<T, false>::value,
"Second template parameter needs to be of function type.");
};
template<typename C, typename Ret, typename... Args>
struct has_insert_method<C, Ret(Args...)>
{
private:
template<typename T>
static constexpr auto check(T*) -> typename std::is_same<decltype(std::declval<T>().insert(std::declval<Args>()...)), Ret>::type;
template<typename>
static constexpr std::false_type check(...);
typedef decltype(check<C>(0)) type;
public:
static constexpr bool value = type::value;
};
int main()
{
typedef std::vector<int> v;
std::cout << "Does vector have an insert method?: " << has_insert_method<v, std::pair<v::iterator, bool>(v::value_type const&)>::value;
std::cout << std::endl;
typedef std::set<int> t;
std::cout << "Does set have an insert method?: " << has_insert_method<t, std::pair<t::iterator, bool>(t::value_type const&)>::value;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxzZXQ+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSwgdHlwZW5hbWUgVD4Kc3RydWN0IGhhc19pbnNlcnRfbWV0aG9kCnsKCXN0YXRpY19hc3NlcnQoc3RkOjppbnRlZ3JhbF9jb25zdGFudDxULCBmYWxzZT46OnZhbHVlLAoJCQkJICAiU2Vjb25kIHRlbXBsYXRlIHBhcmFtZXRlciBuZWVkcyB0byBiZSBvZiBmdW5jdGlvbiB0eXBlLiIpOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgQywgdHlwZW5hbWUgUmV0LCB0eXBlbmFtZS4uLiBBcmdzPgpzdHJ1Y3QgaGFzX2luc2VydF9tZXRob2Q8QywgUmV0KEFyZ3MuLi4pPgp7CnByaXZhdGU6Cgl0ZW1wbGF0ZTx0eXBlbmFtZSBUPgoJc3RhdGljIGNvbnN0ZXhwciBhdXRvIGNoZWNrKFQqKSAtPiB0eXBlbmFtZSBzdGQ6OmlzX3NhbWU8ZGVjbHR5cGUoc3RkOjpkZWNsdmFsPFQ+KCkuaW5zZXJ0KHN0ZDo6ZGVjbHZhbDxBcmdzPigpLi4uKSksIFJldD46OnR5cGU7CgoJdGVtcGxhdGU8dHlwZW5hbWU+CglzdGF0aWMgY29uc3RleHByIHN0ZDo6ZmFsc2VfdHlwZSBjaGVjayguLi4pOwoKCXR5cGVkZWYgZGVjbHR5cGUoY2hlY2s8Qz4oMCkpIHR5cGU7CgpwdWJsaWM6CglzdGF0aWMgY29uc3RleHByIGJvb2wgdmFsdWUgPSB0eXBlOjp2YWx1ZTsKfTsKCmludCBtYWluKCkKewoJdHlwZWRlZiBzdGQ6OnZlY3RvcjxpbnQ+IHY7CglzdGQ6OmNvdXQgPDwgIkRvZXMgdmVjdG9yIGhhdmUgYW4gaW5zZXJ0IG1ldGhvZD86ICIgPDwgaGFzX2luc2VydF9tZXRob2Q8diwgc3RkOjpwYWlyPHY6Oml0ZXJhdG9yLCBib29sPih2Ojp2YWx1ZV90eXBlIGNvbnN0Jik+Ojp2YWx1ZTsKCXN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7CgoJdHlwZWRlZiBzdGQ6OnNldDxpbnQ+IHQ7CglzdGQ6OmNvdXQgPDwgIkRvZXMgc2V0IGhhdmUgYW4gaW5zZXJ0IG1ldGhvZD86ICIgPDwgaGFzX2luc2VydF9tZXRob2Q8dCwgc3RkOjpwYWlyPHQ6Oml0ZXJhdG9yLCBib29sPih0Ojp2YWx1ZV90eXBlIGNvbnN0Jik+Ojp2YWx1ZTsKCglyZXR1cm4gMDsKfQo=