读书人

函数模板的有关问题c++primer课后习

发布时间: 2013-08-16 14:29:57 作者: rapoo

求助:函数模板的问题,c++primer课后习题
题目:
16.9 编写行为类似于标准库中find算法的模板。你的模板应接受一个类型形参,该形参指定函数形参(一对迭 代器)的类型。使用你的函数在vector<int> 和vector<string>中查找给定值。

我写的函数代码:


template<typename T>
typename T::iterator find(typename T::iterator beg, typename T::iterator end, typename T::value_type value)
{
for (; beg != end; ++beg)
{
if (*beg == value)
return beg;
}
return end;
}
//调用代码
viter = find(ivec.begin(), ivec.end(), 3);
siter = find(svec.begin(), svec.end(), string("McHeaven"));


编译平台是vs2010,错误提示为:
error C2783: 'T::iterator find(T::iterator,T::iterator,T::value_type)' : could not deduce template argument for 'T'
我的问题是:
参考答案是用的两个模板形参。我想只用一个,这样的写法为什么不能推断出T的类型。
是不是在函数形参表里面不能像上面的写法来引用模板行参的类型成员?? C++ 模板
[解决办法]
原因是 T::iterator 的写法叫 non-deduced context,意思是说对于 find 的调用,编译器不会从调用实参的类型去推导实例化 find 应该使用的 T 的类型,注意不是说因为信息不全压根推不出来,而是说编译器根本就不会试图去推导。试试下面的声明吧。

template<typename T>
typename T find(T beg, T end, typename std::iterator_traits<T>::value_type value)

[解决办法]
完整的原型,是这个样子的吧。

template<typename Iterator,typename Object> Iterator
find(Iterator beg, Iterator end, const Object &value){
for (; beg != end; ++beg) {
if (*beg == value)
return beg;
}
return end;
}

作为参数,内置类型占用空间,和指针大致相当,或者更大。而对象类型,则可能比较大。
所以对这种模板,value参数,常量引用传递更合适一点。

之所以,会这样,因为,
1)不能由Iterator的类型,直接推导出value的类型是Object。
因为 C++ 原生指针,也可以当做Iterator使用。
这是STL 的标准做法。


2)模板不能逆向推导

template<typename T> typename T::iterator find(typename T::iterator beg, typename T::iterator end, typename T::value_type value) { for (; beg != end; ++beg) { if (*beg == value) return beg; } return end; }
这是逆向推导
由函数参数类型,typename T::iterator,typename T::value_type 逆向推导模板参数 T,
这不是C++模板,类型推导,所能够做到的。

读书人网 >C++

热点推荐