Search code examples
c++templatesvisual-c++variadic-templatestemplate-argument-deduction

Template type deduction with variadic template for function calls


I'm using VC++ /std:c++latest and I want to determine the RET-Type, Class-Type and argument types of a member function passed as template paramter to a struct. I found a way to do this:

template <auto MEMBER>
class C;
template <class RET, class T, class... ARGS, RET(T::*MEMBER)(ARGS...)>
class C<MEMBER>
{
public:
    template <class... ARGS2>
    RET operator()(ARGS2&&... args)
    {
        // place holder
        (reinterpret_cast<T*>(0)->*MEMBER)(std::forward<ARGS2>(args)...);
    }
};
struct A
{
    void f(int, int) {}
};
int main()
{
    C<&A::f> c; // error C2079: 'instance' uses undefined class 'C'
    c(5, 5);
}

But this solution is only working with g++.

So

  1. is this a bug in VC++?
  2. is there an other way to achieve the same thing?

Solution

  • The hint of @max66 let me figure out, that I do not need to deduce the arguments of the function, whereat the return type and class type can easily be deduced.

    template <auto MEMBER>
    struct C
    {
        template <class RET, class T, class... ARGS>
        static constexpr auto deduce_RET(RET (T::*member)(ARGS...)) -> RET;
        template <class RET, class T, class... ARGS>
        static constexpr auto deduce_T(RET (T::*member)(ARGS...)) -> T;
        using RET = decltype(deduce_RET(MEMBER));
        using T = decltype(deduce_T(MEMBER));
        template <class... ARGS>
        RET operator()(ARGS&&... args)
        {
            return (reinterpret_cast<T*>(0)->*MEMBER)(std::forward<ARGS>(args)...);
        }
    };
    

    Edit: The bug got fixed for Visual Studio 2019: https://developercommunity.visualstudio.com/content/problem/464355/error-c2079-instance-uses-undefined-class-c.html