В книге Стенли Липпмана(Базовый курс по с++) написано, что если тип возвращаемый шаблонной функцией отличается от типа параметра шаблона, то можно использовать замыкание:
template<typename Iterator>
auto process(const Iterator& beg, const Iterator& end)->decltype(*beg) {
/*SOMECODE*/
return *end;
}
Вопрос 1:
Если возвращаемый тип будет результатом сложных вычислений, мне дублировать их в decltype(/вычисления/)?
Вопрос 2:
Какие преимущества использование замыкания по сравнению с использованием спецификатора auto для выведения возвращаемого типа (код далее)
template<typename Iterator>
auto process(const Iterator& beg, const Iterator& end) {
/*SOMECODE*/
return *end;
}
Не совсем понимаю, что и почему вы называете "замыканием".
Если возвращаемый тип будет результатом сложных вычислений, мне дублировать их в decltype(/вычисления/)?
Да, если вы хотите воспользоваться именно C++11 синтаксисом с -> decltype(что-то)
.
Однако начиная с C++14 у вас есть возможность использовать auto
(или decltype(auto)
) в качестве типа возвращаемого значения и не указывать этот хвост с -> decltype(что-то)
вообще. В такой ситуации тип возвращаемого значения будет выведен автоматически из типа аргумента return
.
Вопрос 2: Какие приемущества использование замыкания по сравнению с использованием спецификатора auto для выведения возвращаемого типа
Преимущества заключаются в том, что вариант -> decltype(что-то)
сразу жестко задает тип возвращаемого значения функции. После этого в return
можно указывать значения других типов - и они будут как обычно приводиться к типу возврата функции.
В выводимом варианте такой возможности нет. Если разные return
будут возвращать значения разных типов, тот дедукция будет неоднозначной и код просто не будет компилироваться.
То есть это совершенно разные модели поведения и дело тот не в преимуществах, а в том, какая именно модель вам нужна: 1) жестко заданный тип с приведением, или 2) выводимый тип с требованием единообразия.
Тут стоило бы начать с того, что правила вывода типа для auto
и decltype
различны. Например, если в качестве Iterator
используется std::vector<std::string>::iterator
, то возвращаемые типы будут различны:
std::string
(иницилизированный вызовом конструктора копирования).template<typename Iterator>
auto process(const Iterator& beg, const Iterator& end)
template<typename Iterator>
auto process(const Iterator& beg, const Iterator& end) -> std::remove_reference_t<decltype(*beg)>
std::string &
template<typename Iterator>
decltype(auto) process(const Iterator& beg, const Iterator& end)
template<typename Iterator>
auto process(const Iterator& beg, const Iterator& end) -> decltype(*beg)
Кроме того, автоматический вывод типа не может быть использован, если функция вызывается до ее определения.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Установил Clang по гайду и обнаружил, что LLVM\include нет папок clang и llvm (есть clang-с и llvm-с)
Дано два динамических массива одинаковой размерностиНужно вывести массив с одинаковыми элементами этих массивов
Картинка почему то постоянно обновляется, и происходит постоянное выделение памяти без освобождения