我有非常简单的代码:
#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()
函数,但无论出于何种原因,这都会破坏代码。我遇到的唯一错误是无法推断参数“T”,对于 int ex_count()
,即使使用常量而不是对象( Function match
)工作得很好。
我应该指出,除了我要问的问题之外,我不会寻求其他任何建议。代码过于复杂且毫无意义——我知道,但这不是我的设计。
有什么问题吗?
为了清楚起见,错误:
note: candidate template ignored: couldn't infer template argument 'T'
int ex_count(typename list<T>::iterator v, typename list<T>::iterator v2, Function match)
编辑:
有人告诉我,由于::
而无法推断出它。运算符,但为什么这个版本的代码仅在使用 ::
时才有效?运算符:
#include <iostream>
#include <list>
using namespace std;
template <typename T>
int ex_count(typename list<T>::iterator v, typename list<T>::iterator v2, 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(), v.end(), 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)
但是它按照我上面写的方式编译得很好。
那么是什么原因导致的呢?
最佳答案
模板参数T
无法推断,因为 non-deduced context .
In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
- The nested-name-specifier (everything to the left of the scope resolution operator
::
) of a type that was specified using a 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(), v.end(), 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(), v.end(), target);
,第一个和第二个函数参数 T
将被推导为 list<int>::iterator
,在第 3 个时,它将被推导为 int
,它们是矛盾的。
如果你将模板参数分开那就没问题了。
template <typename Iterator, typename T>
int ex_count(Iterator v, Iterator v2, T target)
关于c++ - 无法推断模板参数 'T',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63940030/