Учитывая тип C, который является контейнером, совместимым с STL, как правильно определить, содержит ли C функцию-член reserve? Я попробовал следующий подход (с GCC 4.6.3):
template< typename C, typename = void >
struct has_reserve
: std::false_type
{};
template< typename C >
struct has_reserve< C, typename std::enable_if<
std::is_same<
decltype( &C::reserve ),
void (C::*)( typename C::size_type )
>::value
>::type >
: std::true_type
{};
Это работает для C std::vector, но не для неупорядоченных контейнеров, например. std::unordered_set. Причина в том, что reserve является (прямой) функцией-членом std::vector, но для неупорядоченных контейнеров она наследуется от базового класса, то есть ее подпись не void (C::*)( typename C::size_type ), а void (B::*)( typename C::size_type ) для некоторой неопределенной базы class B of C.
Я знаю, как обойти его и обнаружить reserve, даже если он унаследован, но он выглядит неуклюжим, и мне интересно, что разрешено стандартом. Так что...
Мой вопрос: позволяет ли стандарт reserve унаследоваться от неуказанного базового класса или является привязкой к синопсису и требует прямой функции-члена?