使用variadic模板进行函数调用的模板类型扣除

Template type deduction with variadic template for function calls

本文关键字:类型 variadic 使用 函数调用      更新时间:2023-10-16

我正在使用VC /std:c++latest,我想确定成员函数的ret-type,类类型和参数类型作为模板参数传递给struct。我找到了这样做的方法:

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);
}

,但此解决方案仅与G 一起工作。

so

  1. 这是VC ?
  2. 中的错误
  3. 有其他方法可以实现同一件事吗?

不是答案(对不起),而是一个长评论:如果您想要完美的转发,则需要模板函数中的通用引用/方法

我的意思是...我建议重写operator()如下或类似的内容(我还为T对象添加了完美的转发)

template <typename U, typename ... As>
RET operator()(U && u, As && ... args)
{
    (std::forward<U>(u).*MEMBER)(std::forward<As>(args)...);
}

,您可以写(至少在g 和clang 中)

A  a;
C<&A::f> c;
c(a, 5, 5);

@max66的提示让我弄清楚,我不需要推断该函数的参数,可以轻松推导返回类型和类型。

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)...);
    }
};

编辑:该错误已修复为Visual Studio 2019:https://develovelerCommunity.visualstudio.com/content/problem/464355/error-c2079-instance-uses-uses-use-uns-unsundelist-undecin--class-undefined-class-class-class-c.html/div>