Ответ 1
Единственный возможный тип возвращаемой функции возврата в С++ 11 - это возвращаемый тип лямбда. Однако С++ 11 ограничивает использование лямбда. Это работает:
auto add = [](int a, int b) { return a + b; };
Это допустимо и определяет add
как лямбда, которая определяет функцию-член operator()
, которая возвращает int
. Поскольку лямбда ничего не захватывает, вы даже можете написать
auto add = +[](int a, int b) { return a + b; };
чтобы сделать add
регулярным указателем на функцию: он получает тип int(*)(int, int)
.
Однако С++ 11 не позволяет указывать типы параметров как auto
или не допускать, чтобы add
определялось как переменная шаблона, поэтому вы не можете использовать это, чтобы в общем случае выводить тип возвращаемого значения. Попытка обернуть его в класс шаблона не удалась:
template <typename A, typename B>
struct S { static auto add = [](A a, B b) { return a + b; }; }; // invalid
Недопустимо инициализировать add
в классе, и вы не можете использовать auto
, если член не инициализирован в классе. Кроме того, даже если бы это сработало, это не позволило бы вычесть A
или B
, что, похоже, больше того, что вам нужно.
Учитывая эти ограничения, я не вижу альтернативы, кроме как повторять выражение. Однако вы можете скрыть повторение в тривиальном макросе.
#define AUTO_RETURN(func, ...) auto func -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
AUTO_RETURN(add(A a, B b), a + b)
Или вариант, отмеченный Марк Глисс,
#define RETURNS(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
auto add(A a, B b) RETURNS(a + b)
который выглядит немного чище.
В Boost может быть что-то вроде этого, я не знаю. Несмотря на тривиальность, Boost кажется излишним здесь.