gpt4 book ai didi

c++ - 从模板函数中取消引用的迭代器推断类型

转载 作者:搜寻专家 更新时间:2023-10-31 01:35:31 25 4
gpt4 key购买 nike

我正在完成“Accelerated C++”中的练习,我发现了一些我不理解的关于编译器如何在函数模板中推断类型的行为。在练习 10-2 中,我们被要求编写一个模板函数,该函数可以计算 vector 或内置数组中算术类型列表的中位数。我偶然发现了这个问题的示例解决方案,它涉及一个模板函数,该函数计算并返回两个迭代器之间的容器中值,即我创建了以下名为“median.hpp”的文件:

#ifndef median_hpp
#define median_hpp

#include <algorithm>
#include <stdexcept>
#include <vector>

using std::domain_error;
using std::sort;
using std::vector;

template <class T, class Iterator>
T median(Iterator begin, Iterator end) {

//check if the container is empty
if (begin == end)
throw domain_error("median of an empty container");

//create a vector with the same type as the container
//and copy the container contents into it
vector<T> temp;

for ( ; begin != end; ++begin)
temp.push_back(*begin);

//sort the temporary vector, and compute and return the median
sort(temp.begin(), temp.end());

size_t mid = temp.size() / 2;

T ret = (temp.size() % 2 == 0)
? (temp[mid] + temp[mid - 1]) / 2
: temp[mid];

return ret;
}

#endif /* median_hpp */

因此,如果我想计算数组和 vector 的中值以证明此函数适用于两种容器类型,我将使用上述模板函数,如下所示:

#include <iostream>
#include <vector>
#include "median.hpp"

using std::vector;
using std::cout;
using std::cin;
using std::endl;

int main()
{

int arr[] = {12,2,4,1,4,56,1};

const size_t nData = sizeof(arr)/sizeof(*arr);
vector<double> v(arr, arr + nData);

cout << median(v.begin(),v.end()) << endl;
cout << median(arr, arr + nData) << endl;

return 0;
}

但是,由于我不明白的原因,我得到以下错误:

没有匹配函数调用“中位数”...忽略候选模板:无法推断模板参数“T”

据我所知,问题在于编译器无法从取消引用的迭代器中推断出“T”的类型。我想知道

一个。为什么会这样?

B.有什么优雅的方法可以解决这个问题吗?

最佳答案

编译器可以推断Iterator,但不能推断T。那是因为 oterator 无法说明如何从您传递给它的任何内容中推断出 T迭代器?从未知的 Iterator 类型,如果不知道 Iterator 实际上是什么,您怎么能知道 T 是什么?编译器根本不知道这一点。

但是,由于您知道 Iterator 是一个实际的迭代器类型,并且大多数迭代器都有返回到包含的类型 T 的类型别名,您可以执行类似

template <class Iterator, class T = typename std::iterator_traits<Iterator>::value_type>
T median(Iterator begin, Iterator end) { ... }

有关所有这些的信息可以从例如this std::vector reference它告诉您 vector 中的 iterator 类型是 random access iterator其中提到 value_type 以及如何从 std::iterator_traits 中找到它.

std::iterator_traits应该可以用于所有标准迭代器,而不仅仅是 std::vector 给出的随机访问迭代器。

关于c++ - 从模板函数中取消引用的迭代器推断类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37241120/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com