Can someone explain to me how can I check for existence of a class member function template specializations with C++17? I have tried solution from this answer and it works fine for normal functions:
template<typename, template<typename> class, typename = void_t<>>
struct detect : std::false_type {};
template<typename T, template<typename> class Op>
struct detect<T, Op, void_t<Op<T>>> : std::true_type {};
template<typename T>
using simple_func_t = decltype(std::declval<T>().SimpleFunc());
template<typename T>
using has_simple_func = detect<T, simple_func_t>;
class Test
{
public:
int SimpleFunc()
{
cout << "SimpleFunc\n";
return 0;
}
};
void Foo()
{
if constexpr (has_simple_func<Test>())
{
Test test;
test.SimpleFunc();
}
}
The problem is that I can not make it work for specialized member functions. I have tried that:
template<typename, template<typename> class, typename = void_t<>>
struct detect_ver : std::false_type {};
template<typename T, template<typename> class Op>
struct detect_ver<T, Op, void_t<Op<T>>> : std::true_type {};
template<typename T, int version>
using template_func_t = decltype(std::declval<T>().TemplateFunc<version>());
template<typename T, int version>
using has_template_func = detect_ver<T, template_func_t<T, version>>;
class Test
{
public:
template<int version>
int TemplateFunc();
template<>
int TemplateFunc<1>()
{
cout << "TemplateFunc1\n";
return 1;
}
};
void Foo()
{
if constexpr (has_template_func<Test, 1>())
{
Test test;
test.TemplateFunc<1>();
}
}
But I keep getting strange compile errors like this:
error C2760: syntax error: unexpected token ')', expected 'expression'
for line:
using template_func_t = decltype(std::declval<T>().TemplateFunc<version>());
UPDATE: I have tried solution provided by jarod. It compiles, but detect_ver deducted as false_type. I do use MSVC.