C ++模板方法未知返回类型

时间:2018-09-28 15:52:20

标签: c++ templates iterator c++14 auto

我遇到了我不遵循的一段代码。请考虑以下两种方法。

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 :(得分:2)

  

[dcl.spec.auto]

     

如果函数的声明的返回类型包含占位符类型,则从函数主体中未丢弃的返回语句(如果有)中推断出该函数的返回类型

还有

  

如果具有包含占位符类型的已声明返回类型的函数具有多个未丢弃的返回语句,则为每个此类返回语句推导返回类型。如果每次推导的类型都不相同,则程序格式错误。

废弃的语句是出现在 constexpr if 语句 [stmt.if] 的未采用分支中的语句。

答案 1 :(得分:1)

C ++ 14使我们能够编写具有推论返回类型的函数:

auto foo() { return 5; }

在C ++ 11中,这是格式错误的-您需要以某种方式指定返回类型。在C ++ 14中,我们可以从return语句中保守地推断出返回类型。保守地说,我的意思是如果有多个-它们都必须是同一类型,并且如果递归,则需要递归第二个而不是第一个。

推论遵循正常的模板推论规则。所以这个:

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

返回一个int,而不是int&

所有这些,是的,FindElementV1是一个完全有效的函数模板...从C ++ 14开始。