Ваши подозрения неверны.
void f() { }
Теперь deduce(&f)
имеет тип void
, но с вашим переписыванием он имеет тип void(*)()
. В любом случае, везде, где вы хотите получить тип выражения или объявления, вы используете decltype
(обратите внимание на тонкую разницу между этими двумя. decltype(x)
не обязательно совпадает с decltype((x))
).
Например, вполне вероятно, что ваша реализация Стандартной библиотеки где-то содержит строки вроде
using size_t = decltype(sizeof(0));
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);
Поиск правильного типа возврата add
было сложной проблемой на протяжении всего C ++. Теперь это простое упражнение.
template<typename A, typename B>
auto add(A const& a, B const& b) -> decltype(a + b) { return a + b; }
Малоизвестно, что вы можете использовать decltype
до ::
и в псевдодеструкторном имени
// has no effect
(0).~decltype(0)();
// it and ite will be iterators into an initializer list
auto x = { 1, 2, 3 };
decltype(x)::iterator it = x.begin(), ite = x.end();