Метод шаблона C ++ неизвестный тип возвращаемого значения - PullRequest
0 голосов
/ 28 сентября 2018

Я наткнулся на кусок кода, которому я не следую.Рассмотрим следующие 2 метода:

template <typename T>
auto FindElementV1(std::vector<T> elementList, const T& element) {
 return std::find(elementList.begin(), elementList.end(), element);     
}

template <typename T>
auto FindElementV2(std::vector<T> elementList, const T& element) -> typename decltype(elementList)::iterator {
 return std::find(elementList.begin(), elementList.end(), element);     
}

Я могу понять, FindElementV2 работает, так как тип возвращаемого значения для этого метода указывается с помощью decltype.Но почему FindElementV1 работает без указания типа возвращаемого значения?Является ли V1 стандартным совместимым фрагментом кода?

Ниже приведен полный рабочий пример.Соблюдается GCC 6.3

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
auto FindElementV1(std::vector<T> elementList, const T& element) {
 return std::find(elementList.begin(), elementList.end(), element);     
}

int main() {
    std::vector<int> vec = {1,4,2,4,3,5,3,5,3,6};
    auto it = FindElementV1(vec, 5); //< Why does this work without a return type in the method?
    cout<<*it<<endl;
}

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

C ++ 14 дал нам возможность писать функции с выведенным типом возврата:

auto foo() { return 5; }

В C ++ 11 это некорректно - вам нужно как-то указать тип возвращаемого значения.В C ++ 14 мы можем консервативно определить тип возвращаемого значения из операторов return.Под консервативным пониманием я подразумеваю, что если их больше одного - все они должны быть одного типа, и если вы выполняете рекурсию, вам нужно рекурсировать 2-е, а не 1-е.

Вычет следует нормальным правилам вычета по шаблону.Так вот:

auto foo(int& i) { return i; }

возвращает int, а не int&.

Все это говорит о том, что да, FindElementV1 является совершенно допустимым шаблоном функции ... начиная с C ++ 14.

0 голосов
/ 28 сентября 2018

[dcl.spec.auto]

Если объявленный тип возврата функции содержит тип заполнителя, тип возврата функции , выведенный изнеотбрасываемые операторы возврата, если они есть, в теле функции

, а также

Если функция с объявленным типом возврата, содержащая заполнительУ типа есть несколько неотбрасываемых операторов возврата, тип возврата выводится для каждого такого оператора возврата.Если выводимый тип не является одинаковым при каждом выводе, программа некорректна.

Отбрасываемый оператор - это оператор, который появляется в непроявленной ветви constexpr, если оператор [stmt.if] .

...