Итак, я очень хорошо знаком с парадигмой тестирования, если существует функция-член. В настоящее время этот код работает:
#include <iostream>
#include <type_traits>
struct has_mem_func_foo_impl {
template <typename U, U>
struct chk { };
template <typename Class, typename Arg>
static std::true_type has_foo(chk<void(Class::*)(Arg), &Class::foo>*);
template <typename, typename>
static std::false_type has_foo(...);
};
template <typename Class, typename Arg>
struct has_mem_func_foo : decltype(has_mem_func_foo_impl::template has_foo<Class,Arg>(nullptr)) { };
struct bar {
void foo(int) { }
};
int main() {
static_assert( has_mem_func_foo<bar, int>::value, "bar has foo(int)" );
}
К сожалению, если я сделаю небольшую корректировку:
#include <iostream>
#include <type_traits>
struct has_mem_func_foo_impl {
template <typename U, U>
struct chk { };
template <typename Class, typename... Arg>
static std::true_type has_foo(chk<void(Class::*)(Arg...), &Class::foo>*);
template <typename, typename...>
static std::false_type has_foo(...);
};
template <typename Class, typename... Arg>
struct has_mem_func_foo : decltype(has_mem_func_foo_impl::template has_foo<Class,Arg...>(nullptr)) { };
struct bar {
void foo(int) { }
};
int main() {
static_assert( has_mem_func_foo<bar, int>::value, "bar has foo(int)" );
}
мое статическое утверждение терпит неудачу. У меня создалось впечатление, что вариативные паттерны параметров шаблонов обрабатываются одинаково, когда они расширяются в свои места. Как gcc, так и clang производят неудачное статическое утверждение.
Таким образом, реальный корень моего вопроса - это стандартное поведение? Он также терпит неудачу при тестировании на наличие вариационной функции шаблона-члена.