我写了一个函数,找到任何给定容器中最常见的元素(参见下面的代码),其中输入是该容器的两个const_iterator。如果我使用findMostFrequent(ivec.begin(), ivec.end())
调用此函数,其中ivec
是vector<int>
,则编译器无法推断出模板参数。用findMostFrequent< vector<int> >(ivec.begin(), ivec.end())
调用函数工作正常,但看起来很麻烦。有没有办法让编译器找出要实例化的模板?
template <typename T> typename T::value_type findMostFrequent(typename T::const_iterator beg, typename T::const_iterator end)
{
// T is the type of container, T::value_type is the type which is stored in the container
typename T::size_type current_streak = 0, max_streak = 0;
T::value_type max_so_far;
for (T::const_iterator iter = beg; iter != end; ++iter)
{
current_streak = count(beg, end, *iter);
if ( current_streak > max_streak )
{
max_so_far = *iter;
max_streak = current_streak;
}
}
return max_so_far;
}
答案 0 :(得分:10)
编译器无法推导出嵌套的说明符。 “找到一个具有嵌套说明符的类型,该嵌套说明符等于我看作参数的类型”太复杂,而且通常很难解决它。相反,尝试直接从迭代器中推断出您需要知道的所有内容:
template <typename IteratorType>
typename std::iterator_traits<IteratorType>::value_type
findMostFrequent(IteratorType beg, IteratorType end)
{
typename std::iterator_traits<T>::difference_type current_streak = 0, max_streak = 0;
typename std::iterator_traits<T>::value_type max_so_far;
for (IteratorType iter = beg; iter != end; ++iter)
{
current_streak = count(beg, end, *iter);
if ( current_streak > max_streak )
{
max_so_far = *iter;
max_streak = current_streak;
}
}
return max_so_far;
}
您应该使用std::iterator_traits<T>::value_type
而不是T::value_type
的原因是它使您能够为不自然定义它们的类型(例如指针)使用这些“迭代器规范”。例如,T*
实际上是此代码段的有效迭代器,但它不包含value_type
typedef / type。
答案 1 :(得分:3)
是的,通过使函数接受Iter
模板参数并使用迭代器特征(T
)从中推断<iterator>
- 基本上反过来。
答案 2 :(得分:2)
因为作为模板参数,您必须使用迭代器类型。以下代码效果很好
#include <iostream>
#include <vector>
template <typename IterType>
typename IterType::value_type findMostFrequent(IterType beg, IterType end)
{
// T is the type of container, T::value_type is the type which is stored in the container
unsigned int current_streak = 0, max_streak = 0;
typename IterType::value_type max_so_far;
for (IterType iter = beg; iter != end; ++iter)
{
current_streak = count(beg, end, *iter);
if ( current_streak > max_streak )
{
max_so_far = *iter;
max_streak = current_streak;
}
}
return max_so_far;
}
int main()
{
std::vector<int> v;
for (unsigned int i = 0; i < 10; ++i)
v.push_back(i);
findMostFrequent(v.begin(), v.end());
return 0;
}
在你的代码中,迭代器类型与vector没有任何关系,因此编译器无法推导出模板参数