Как можно использовать Boost для достижения типов автоматического возврата в стиле C++14?
Предположим, у меня есть функция, которая складывает два значения. Если я ничего не знаю о типах, то я в основном должен написать свою функцию дважды; один раз в фактическом возвращаемом значении и снова в качестве спецификатора возвращаемого типа:
template <typename A, typename B>
auto Add(const A& a, const B& b) ->std::decay<decltype(a + b)>::type
{
return a + b;
}
в то время как это работает, это нежелательно, потому что трудно читать и трудно поддерживать.
в C++14 это не будет проблемой, потому что мы можем удалить спецификатор возвращаемого типа (я не уверен, что он будет делать распад, хотя...). Пока, Я застрял с C++11.
это был мой опыт, что всякий раз, когда я ищу функцию в C++, которая еще не пробилась в стандарт, но для которой есть очевидная необходимость,библиотека обычно имеет решение. Я просмотрел документацию, но не нашел ничего, что могло бы мне помочь. Элемент BOOST_AUTO_RETURN и BOOST_TYPEOF_TPL функции, похоже, больше направлены на предоставление функциональности C++11 для пользователей C++03.
в основном то, что я после этого что-то, что выполняет следующие функции:
template <typename A, typename B>
auto Add(const A& a, const B& b)
{
return a + b; // Deduce return type from this, like C++14 would
}
есть ли какая-то функциональность в библиотеке Boost, о которой я не знаю (или отличный трюк в C++11), который может позволить мне отказаться от явного -> decltype(...) после каждого типа автоматического возврата? Как это будет реализовано?
2 ответа:
единственный возможный выводимый тип возврата функции в C++11-это тип возврата лямбды. Однако C++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).Однако, C++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 здесь кажется излишним.