将一个指向成员函数的指针转换为另一个相同的 class

Cast one pointer-to-member-function to another of same class

使用 reinterpret_cast 将指向成员函数的指针转换为同一 class 的另一个指向成员函数的指针是否合法?以下示例有效。但它合法吗?

#include<iostream>
#include<vector>
#include<string>

class A
{
    public:
    void func_int(int x) { std::cout << x << std::endl; }
    void func_string(std::string const& x) { std::cout << x << std::endl; }
};

int main()
{
    std::vector<void(A::*)()> v;
    v.push_back(reinterpret_cast<void(A::*)()>(&A::func_int));
    v.push_back(reinterpret_cast<void(A::*)()>(&A::func_string));
    A a;
    (a.*reinterpret_cast<void(A::*)(int)>(v[0]))(5);
    (a.*reinterpret_cast<void(A::*)(std::string const&)>(v[1]))(std::string{"Test"});

    return 0;
}

[expr.reinterpret.cast],C++ 草案指出:

A prvalue of type “pointer to member of X of type T1” can be explicitly converted to a prvalue of a different type “pointer to member of Y of type T2” if T1 and T2 are both function types or both object types.72 The null member pointer value ([conv.mem]) is converted to the null member pointer value of the destination type. The result of this conversion is unspecified, except in the following cases:

  • converting a prvalue of type “pointer to member function” to a different pointer to member function type and back to its original type yields the original pointer to member value.

  • converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data member of Y of type T2” (where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer to member value.

72) T1 and T2 may have different cv-qualifiers, subject to the overall restriction that a reinterpret_cast cannot cast away constness.

由于您将 "pointer to member function" 转换为不同的 "pointer to member function" 类型并返回,它会产生原始值。这既是合法的又是明确定义的行为。所以你的代码应该可以正常工作。