Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ : syntax for is_member_function_pointer in a template declaration

Tags:

c++

templates

I have a template with a declaration similar to this:

template <typename Arg0, typename... Args>
class blah {};

I have two versions of the template, and I want to use one when Arg0 is a member function pointer, otherwise use the other one. I'm trying to use std::enable_if and std::is_member_function_pointer but I cannot find the correct syntax. This is what I have for the true case:

template<typename = typename std::enable_if< std::is_member_function_pointer<Arg0> >::type, typename... Args>
class blah() {}

But this obviously isn't syntactically correct.

like image 725
gimmeamilk Avatar asked Apr 26 '26 04:04

gimmeamilk


2 Answers

When using the Boolean predicates with classes there are generally two approaches I use to make the choice:

  1. If I just need to choose between two types, I use sonething like

    typename std::conditional<
        std::is_member_function_pointer<F>::value,
            type_when_true, type_when_false>::type
    
  2. If things need to change more than that I derive from a base which is specialized on a Boolean covering the two implementation choices:

    template <bool, typename...>
    struct helper;
    
    template <typename... A>
    struct helper<true, A...> {
        // implementation 1
    };
    template <typename... A>
    struct helper<false, A...> {
        // the other 1
    };
    template <typename F, typename... A>
    struct actual
        : helper<std::is_member_function_pointer<F>::value, F, A...>
    {
        // typedefs, using ctors, common code, etc.
    };
    
like image 199
Dietmar Kühl Avatar answered Apr 28 '26 18:04

Dietmar Kühl


Maybe "ordinary" partial specialization is sufficient?

template<class Arg0>
struct blah { bool value = false; };

template<class Ret, class C, class... Args>
struct blah < Ret (C::*)(Args...) >
{ bool value = true; };

struct test
{
    int foo(double&);
};

#include <iostream>
#include <iomanip>
int main()
{
    std::cout << std::boolalpha;
    std::cout << blah<decltype(&test::foo)>().value << std::endl;
    std::cout << blah<int>().value << std::endl;
}
like image 31
dyp Avatar answered Apr 28 '26 17:04

dyp