Я хотел бы преобразовать указатель функции константного выражения в 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;
}