将函数转换为成员函数
Cast function to member-function
我想将函数转换为成员函数然后调用它,但是self
对此有一些调整self_3 = self_1 + self_2
struct Foo {};
namespace FooExt {
Foo* getSelf(Foo *self) {
return self;
}
};
template <typename R, typename T, typename... Args>
auto f2mf(R(func)(T*, Args...)) -> R(T::*)(Args...) {
return (R(T::*&)(Args...)) func;
}
int main() {
auto getSelf = f2mf(FooExt::getSelf); // getSelf: (Foo* (Foo::*)(Foo* const)) 0x557f0a9ac210 <FooExt::getSelf(Foo*)>, this adjustment 140735536657056
Foo f{};
auto self_1 = &f;
auto self_2 = (((Foo*) nullptr)->*getSelf)();
auto self_3 = (f.*getSelf)();
return 0;
}
原因是什么?如何正确执行此操作?
下面的推理是错误的,因为 1. 成员函数指针不是函数指针,并且 2. 您实际上不是转换为成员函数指针类型,而是转换为成员函数指针引用类型。
当您从强制转换获得的引用中初始化 f2mf
的 return 值时,这里的未定义行为已经发生。它访问具有错误类型的引用指针,导致别名冲突和未定义的行为。
将函数指针显式转换为另一种函数指针类型的结果未指定,除非转换回原始类型会产生原始指针值。
通过指向不等于原始函数类型的函数类型的指针调用函数会导致未定义的行为。
因此,您的编译器可以对代码中的指针值做任何它想做的事情。
此外,在空指针值上调用成员函数也会导致未定义的行为,并且还允许编译器做任何它想做的事情。
我想将函数转换为成员函数然后调用它,但是self
对此有一些调整self_3 = self_1 + self_2
struct Foo {};
namespace FooExt {
Foo* getSelf(Foo *self) {
return self;
}
};
template <typename R, typename T, typename... Args>
auto f2mf(R(func)(T*, Args...)) -> R(T::*)(Args...) {
return (R(T::*&)(Args...)) func;
}
int main() {
auto getSelf = f2mf(FooExt::getSelf); // getSelf: (Foo* (Foo::*)(Foo* const)) 0x557f0a9ac210 <FooExt::getSelf(Foo*)>, this adjustment 140735536657056
Foo f{};
auto self_1 = &f;
auto self_2 = (((Foo*) nullptr)->*getSelf)();
auto self_3 = (f.*getSelf)();
return 0;
}
原因是什么?如何正确执行此操作?
下面的推理是错误的,因为 1. 成员函数指针不是函数指针,并且 2. 您实际上不是转换为成员函数指针类型,而是转换为成员函数指针引用类型。
当您从强制转换获得的引用中初始化 f2mf
的 return 值时,这里的未定义行为已经发生。它访问具有错误类型的引用指针,导致别名冲突和未定义的行为。
将函数指针显式转换为另一种函数指针类型的结果未指定,除非转换回原始类型会产生原始指针值。
通过指向不等于原始函数类型的函数类型的指针调用函数会导致未定义的行为。
因此,您的编译器可以对代码中的指针值做任何它想做的事情。
此外,在空指针值上调用成员函数也会导致未定义的行为,并且还允许编译器做任何它想做的事情。