gpt4 book ai didi

c++ - 在编译时将函数指针转换为 std::uintptr_t

转载 作者:行者123 更新时间:2023-11-30 01:34:18 27 4
gpt4 key购买 nike

我想在编译时将常量表达式函数指针转换为 std::uintptr_t。我该怎么做?

这是一个最小的例子:

#include <cstdint>
void fn() {}
int main(int argc, char** argv) {
constexpr void* ptr = (void *) fn;
constexpr std::uintptr_t idx = reinterpret_cast<std::uintptr_t>(fn);
return 0;
}

GCC 7/8/9 目前给我错误“在常量表达式中从指针类型转换为算术类型 std::uintptr_t”。然而,我的理解是 std::uintptr_t 应该能够容纳任何指针类型,这意味着这应该能够在常量表达式中完成。

背景

为了说明为什么我需要这个,我想 (1) 在编译时检索函数指针的地址,(2) 将其转换为 std::uintptr_t,然后 (3) 将其作为模板参数传递,以便在编译时将其烘焙到函数中。

这意味着成为 RPC 引擎的一部分,类似于这段代码,它会产生非常相似的错误:

#include <cstdio>
#include <cstdint>

template <std::uintptr_t FnPtr, typename Fn>
void fn_handler() {
((Fn *) FnPtr)();
}

int main(int argc, char** argv) {
auto lel = []() {
printf("Hi, fam!\n");
};
// Note that +lel is an implement 0+lel, converting
// the lambda to a fn ptr.
constexpr void* ptr = reinterpret_cast<void*>(+lel);
constexpr std::uintptr_t idx = reinterpret_cast<std::uintptr_t>(ptr);

fn_handler<idx, decltype(lel)>();
return 0;
}

最佳答案

However, my understanding was that std::uintptr_t should be able to hold any pointer type, meaning this should be able to be done in a constant expression.

当然。但是 reinterpret_cast 从不 允许在常量表达式中使用。因为这是将指针转换为整数的唯一方法,所以这不是您在编译时可以做的事情。

如果你想传递一个函数指针作为模板参数,那么just do that :

int func() {return 0;}

template<int (*pfn)()>
int fn_handler()
{
return pfn();
}

...

fn_handler<&func>();

如果你想让函数的类型成为模板参数,然后是 C++17 之前的版本,你可以像这样使用老技巧:

template<typename Fn, Fn pfn>
decltype(auto) fn_handler()
{
return pfn();
}

...

fn_handler<decltype(&func), &func>();

C++17 让我们只使用auto:

template<auto pfn>
decltype(auto) fn_handler()
{
return pfn();
}

...

fn_handler<&func>();

关于c++ - 在编译时将函数指针转换为 std::uintptr_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56658810/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com