c++ - C++获取重载成员函数指针的常用方法
问题描述
获取重载成员函数(具有替代调用约定的真实成员和静态成员)地址的常用方法是什么?
在替代调用约定的情况下,以下示例将失败:
#include <iostream>
using namespace std;
struct A {
int mem(int a) {
return a * 2;
};
int mem(int a, int b) {
return a + b;
}
static int stat(int a) {
return a * 2;
}
static int stat(int a, int b) {
return a + b;
}
};
int main() {
A a;
cout << "a.mem(1) -> " << a.mem(1) << endl;
cout << "a.mem(1, 2) -> " << a.mem(1, 2) << endl;
cout << "A::stat(1) -> " << A::stat(1) << endl;
cout << "A::stat(1, 2) -> " << A::stat(1, 2) << endl;
cout << "a.stat(1) -> " << a.stat(1) << endl;
cout << "a.stat(1, 2) -> " << a.stat(1, 2) << endl;
cout << "----------------------------------" << endl;
auto aMem1 = static_cast<int(A::*)(int)>(&A::mem);
cout << "a.*aMem1(1) -> " << (a.*aMem1)(1) << endl;
auto aMem2 = static_cast<int(A::*)(int, int)>(&A::mem);
cout << "a.*aMem2(1, 2) -> " << (a.*aMem2)(1, 2) << endl;
auto stat1 = static_cast<int(*)(int)>(&A::stat);
cout << "stat1(1) -> " << stat1(1) << endl;
auto stat2 = static_cast<int(*)(int, int)>(&A::stat);
cout << "stat2(1, 2) -> " << stat2(1, 2) << endl;
// these fail:
auto aStat1 = static_cast<int(A::*)(int)>(&A::stat);
cout << "a.*aStat1(1) -> " << (a.*aStat1)(1) << endl;
auto aStat2 = static_cast<int(A::*)(int, int)>(&A::stat);
cout << "a.*aStat2(1, 2) -> " << (a.*aStat2)(1, 2) << endl;
return 0;
}
见活的例子。
背景:
我不知道实现是使用成员函数还是静态成员函数,因此,我需要一种通用的方式来处理两者。如上所示,显而易见的方法并不成功。
解决方案
如果您需要能够以&A::x
相同的方式处理表达式,无论x
是静态成员还是非静态成员A
(并且它可能被重载),那么您需要将它传递给其他可以接受R(C::*)(Ts...)
orR(C::*)(Ts...)const
或 or的重载函数R(*)(Ts...)
并相应地发送。像这样的东西:
template <typename... Ts>
struct UniformResolver {
template <typename C, typename R>
constexpr auto operator()(R (C::*func)(Ts...)) const { return resolveMember(func); }
template <typename C, typename R>
constexpr auto operator()(R (C::*func)(Ts...) const) const { return resolveMember(func); }
template <typename R>
constexpr auto operator()(R (*func)(Ts...)) const { return resolveStatic(func); }
private:
template <typename F>
constexpr auto resolveMember(F func) const {
return [func](auto&&... args) {
return std::invoke(func, std::forward<decltype(args)>(args)...);
};
}
template <typename F>
constexpr auto resolveStatic(F func) const {
return [func](auto&&, auto&&... args) {
return std::invoke(func, std::forward<decltype(args)>(args)...);
};
}
};
template <typename... Ts>
constexpr UniformResolver<Ts...> uresolve {};
这为您提供了一个可调用对象模板uresolve
,该模板适应您的函数指针,返回一个可以以统一方式调用并委托给您的函数指针的可调用对象。这是你将如何使用它:
struct A {
int mem(int a) const { return a * 2; }
int mem(int a, int b) const { return a + b; }
static int stat(int a) { return a * 2; }
static int stat(int a, int b) { return a + b; }
};
int main() {
A a;
auto mem1 = uresolve<int>(&A::mem);
auto mem2 = uresolve<int, int>(&A::mem);
auto stat1 = uresolve<int>(&A::stat);
auto stat2 = uresolve<int, int>(&A::stat);
std::cout << mem1(a, 1) << '\n';
std::cout << mem2(a, 1, 2) << '\n';
std::cout << stat1(a, 1) << '\n';
std::cout << stat2(a, 1, 2) << '\n';
}
推荐阅读
- azure - Azure Function is calling itself twice on App service plan
- sql - 如何比较同一张表中的多行?
- ios - 滚动表格视图上的重复复选标记
- r - 在闪亮的 R 中使用 selectInput 来选择和过滤行,而不是选择列
- html - 用 flex 截断文本溢出
- regex - 如何在第二个和第三个正斜杠之间取任何值
- deep-learning - ReLU 什么时候会杀死神经元?
- web-services - 如何使用groovy在soapui中获取标签的值
- git - 在单一存储库中构建微服务的最佳策略是什么?
- angular - “Promise”类型上不存在属性“令牌”
'