dimanche 7 février 2021

Compile time existence checking for a member function with signature fit to variadic parameters pack

I would like to check if there exist a member function with signature fit to a parameter pack. I began with the known SFINAE concept, while trying to extend it for considering also a parameters pack. But at this point I found that I don't know how to do it.

I try to do something like this:

// Note: T object may have several functions with the name foo, but with different signatures.
//       a function foo also can be a template one with variadic parameters pack.
       
template<typename T, typename...Args>
class HAS_FUNCTION_FOO
{
    template<typename U>
    static bool test(decltype(&U::foo));

    template<typename U>
    static float test(...);

public:
    static constexpr bool value = std::is_integral<decltype(test<T>(Args...))>::value;

    //-------------------------------------------------------------^^^^^^^^^
    // how to do it? 

};

I would like to use it for declaring specific object at compile time - something like this:

class Bar
{
public:
    template<typename T, typename...Args>
    void doSomthing(T* p, Args&&...parameters)
    {
        // get correct object type:
        // if T has a function called foo with parameters fits for pack, then declare A, o.w declare B.
        using ObjType = typename std::conditional<HAS_FUNCTION_FOO<T, Args>::value, A, B>::type;

        // compute
        ObjType::doSomthing(p, std::forward<Args>(parameters)...);
    }

private:
    struct A
    {
        template<typename T, typename...Args>
        static void doSomthing(T* p, Args&&...parameters)
        {
            p->foo(std::forward<Args>(parameters)...);
        }
    };

    struct B
    {
        template<typename T, typename...Args>
        static void doSomthing(T* p, Args&&...parameters)
        {
            // do something else
        }
    };

};

Aucun commentaire:

Enregistrer un commentaire