Большое спасибо всем за живые американские горки за полезные комментарии.Кто-то в Reddit, где я задавал тот же вопрос под именем пользователя «TheTiefMaster», отбросил этот «один вкладыш»:
// also works as C
char whatever(unsigned k) { return char(k); } char(*F)(unsigned) = whatever;
Позвольте мне уточнить: я понимаю, что это два утверждения в одной строке.И нет, здесь нет типа, но есть указатель на одну и ту же функцию.Использование:
auto x = whatever(65); // 'A'
auto y = F(66); // 'B'
Тогда я подумал, что следующее сделает определение функции и объявление ее типа:
// FP is a type of function whoever
char whoever(unsigned k) { return 'A'; } typedef char(*FP)(unsigned) ;
Вызов того, кто ведет себя так, как ожидается
auto w = whoever(42) ; // 'A'
FP - то, где это начинает становиться интересным.FP является типом, и, как выясняется, можно привести тип к типу.
// using FP as a type
// c++ style type cast
// empty cast returns nullptr
auto fun = FP();
// calling fun() above crashes
// but it is "invocable" as per C++ rules
static_assert(std::is_invocable_v<P2F()>);
Передача любого аргумента этому приведению, работает и возвращает ненулевой адрес:
// update: this compiles only on MSVC
// and is a bug
auto fun = FP(42);
// type of fun is char (*) (unsigned)
Вызоврезультат этого забавного сбоя, очевидно:
// reading access violation
fun(123) ;
Это приведение с экземпляром из любой требуемой функции работает:
auto fun = FP(whatever);
// works, obviously
fun(65) ; // 'A'
Чтобы использовать эти знания, мы будем использовать static_cast для безопасногоприведение к тому, что мы можем назвать.Приведение типов в C ++ слишком мощное, как и приведение типов в стиле C.
// does not compile
// fun is the wrong type and can not be called
auto fun = static_cast<FP>(42);
// does compile, fun is safe to call
auto fun = static_cast<FP>(whatever);
// works, obviously
fun(65) ; // 'A'
Это исследование, очевидно, еще далеко от завершения.Я продолжу с этим, в другом месте.
Обновление:
using FP = char (*)(int) ;
// must not compile, compiles under MSVC
auto oops = FP(42) ;
Это ошибка в MSVC, о которой я сообщил сегодня.