如何解决无法推断模板参数“ T”
我有非常简单的代码:
#include <iostream>
#include <list>
using namespace std;
template <typename T,typename Function>
int ex_count(typename list<T>::iterator v,typename list<T>::iterator v2,Function match)
{
int count = 0;
while(v != v2)
{
if(match(*v))
count++;
++v;
}
return count;
}
template <typename T>
class ex_eq
{
public:
ex_eq(const T &n_target = T())
{
target = n_target;
}
bool operator() (const T &a)
{
return a == target;
}
private:
T target;
};
int main()
{
list<int> v;
list<int>::iterator iv;
int value;
while (cin >> value)
v.push_back(value);
int target = *v.begin();
int N = ex_count(v.begin(),v.end(),ex_eq<int>(target));
cout << "Found " << N << " instances of " << target << "\n";
}
我最近在Function match
函数中实现了谓词对象int ex_count()
,但是由于任何原因,这都会破坏代码。我得到的唯一错误是,对于int ex_count()
,无法推断出参数'T',即使使用常量而不是对象(Function match
)也可以正常工作。
我应该注意,除了我要问的问题以外,我没有在寻求其他建议。代码过于复杂和毫无意义-我知道,但这不是我的设计。
出什么问题了?
为清楚起见,出现错误:
note: candidate template ignored: couldn't infer template argument 'T'
int ex_count(typename list<T>::iterator v,Function match)
编辑:
有人告诉我,由于::
运算符而无法推断出它,但是为什么为什么此版本的代码仅在使用::
运算符时才起作用:
#include <iostream>
#include <list>
using namespace std;
template <typename T>
int ex_count(typename list<T>::iterator v,T target)
{
int count = 0;
while(v != v2)
{
if(*v == target)
++count;
++v;
}
return count;
}
int main() {
list<int> v;
list<int>::iterator iv;
int value;
while (cin >> value)
v.push_back(value);
int target = *v.begin();
int N = ex_count(v.begin(),target);
cout << "Found " << N << " instances of " << target << "\n";
}
此版本不使用函数对象,而仅使用target
。但是,如果我尝试将ex_count
的参数从list<T>::iterator
更改为T
,则会收到错误消息:
note: candidate template ignored: deduced conflicting types for parameter 'T'
('std::__1::__list_iterator<int,void *>' vs. 'int')
int ex_count(T v,T v2,T target)
但是它的编译方式与上面我写的一样好。
那是什么原因造成的?
解决方法
由于non-deduced context而无法推导出模板参数T
。
在以下情况下,用于构成 P 的类型,模板和非类型值不参与模板自变量的推导,而是使用在其他地方推导的模板自变量或明确指定。如果仅在非推导上下文中使用模板参数并且未明确指定模板参数,则模板参数推导将失败。
- 使用qualified-id指定的类型的嵌套名称说明符(范围解析运算符
::
的所有内容):
您可以显式指定模板参数以绕过模板参数推导,
int N = ex_count<int>(v.begin(),v.end(),ex_eq<int>(target));
或更改功能模板以直接将迭代器类型指定为模板参数。 (它可以与任何迭代器一起使用,包括原始指针。)
template <typename Iterator,typename Function>
int ex_count(Iterator v,Iterator v2,Function match)
{
int count = 0;
while(v != v2)
{
if(match(*v))
count++;
++v;
}
return count;
}
编辑
对于
template <typename T>
int ex_count(typename list<T>::iterator v,typename list<T>::iterator v2,T target)
不会在非推导上下文中执行模板参数推导,然后T
仅在第三函数参数上推导。给定ex_count(v.begin(),target);
T
会被归为int
,并且v.begin()
和v.end()
与类型list<int>::iterator
匹配,一切都很好。
对于
template <typename T>
int ex_count(T v,T v2,T target)
没有非推论上下文,并且将在所有函数参数上推论T
。给定ex_count(v.begin(),target);
,在第一个和第二个函数参数T
上将推论为list<int>::iterator
,在第三个函数参数上将其推论为int
,它们是冲突的。 / p>
如果您将模板参数分开,那就没问题了。
template <typename Iterator,typename T>
int ex_count(Iterator v,T target)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。