【发布时间】:2021-01-02 05:33:31
【问题描述】:
所以我有这样的场景,我想调用一个类的任一函数,其中所讨论的函数具有相同的原型,但它也被重载。因为我知道指向成员的指针,所以我的第一反应是这样的:
struct test
{
int overloaded(char) {}
int overloaded(int) {}
int overloadedone(char) {}
int overloadedone(int) {}
} test;
int main()
{
(test.*(true ? (&test::overloaded) : (&test::overloadedone)))(1);
}
然而事实证明编译器(MSVC - 2019 Preview latest version with std C++ preview)无法推断出类型,我必须写:
(test.*(true ? static_cast<int (test::*)(int)>(&test::overloaded) : static_cast<int (test::*)(int)>(&test::overloadedone)))(1);
反而让我回到了过去:
true ? test.overloaded(1) : test.overloadedone(1);
但我想知道这是否是要求这些演员的定义行为。甚至:
(test.*static_cast<int (test::*)(int)>(true ? (&test::overloaded) : (&test::overloadedone)))(1);
没用。
你必须像第二个例子一样,对三元的两种可能性中的每一种都写下所说的演员表。
【问题讨论】:
-
不存在指向重载的成员函数集的指针。必须执行重载决议,并获取特定重载的地址。该标准定义了几种可能的上下文:在强制转换中,或在初始化或赋值的右侧;强制转换的类型或左侧的类型指导重载解决方案。您正在尝试在这些特定上下文之外获取重载成员函数的地址。
-
表达式
(true ? (&test::overloaded) : (&test::overloadedone)))不起作用,因为overloaded和overloadedone各有两个候选者,每个候选者都有不同的类型。结果是模棱两可。在将static_cast应用于结果之前,需要明确评估该表达式。 -
你可以这样做:godbolt.org/z/bnrM44
-
@PatrickRoberts 不幸的是,这是我正在使用的库,无法控制。
标签: c++ language-lawyer member-function-pointers