用于函数调用的带有可变参数模板的模板类型推导
Template type deduction with variadic template for function calls
我正在使用 VC++ /std:c++latest
并且我想确定作为模板参数传递给的成员函数的 RET 类型、Class 类型和参数类型一个结构。
我找到了一种方法来做到这一点:
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++。
所以
- 这是 VC++ 中的错误吗?
- 是否有其他方法可以达到同样的目的?
不是答案(抱歉)而是长评论:如果你想要完美转发,你需要模板中的通用引用function/method
我的意思是...我建议重写 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的提示让我明白了,我不需要推导函数的参数,而return类型和class类型可以很容易地推导出来。
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://developercommunity.visualstudio.com/content/problem/464355/error-c2079-instance-uses-undefined-class-c.html
我正在使用 VC++ /std:c++latest
并且我想确定作为模板参数传递给的成员函数的 RET 类型、Class 类型和参数类型一个结构。
我找到了一种方法来做到这一点:
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++。
所以
- 这是 VC++ 中的错误吗?
- 是否有其他方法可以达到同样的目的?
不是答案(抱歉)而是长评论:如果你想要完美转发,你需要模板中的通用引用function/method
我的意思是...我建议重写 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的提示让我明白了,我不需要推导函数的参数,而return类型和class类型可以很容易地推导出来。
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://developercommunity.visualstudio.com/content/problem/464355/error-c2079-instance-uses-undefined-class-c.html