I have pretty simple code:
#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";
}
I recently implemented a predicate object Function match into the int ex_count() function, but for whatever reason this breaks the code. The only error I'm getting is that the argument 'T' cannot be inferred, for int ex_count(), even though this was working fine using a constant instead of an object (Function match).
I should note that I'm not looking for advice for anything other than the question I am asking. The code is overly complicated and pointless--I'm aware, but this is not my design.
What's the issue?
Error for clarity:
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)
Edit:
I've been told that it cannot be deduced because of the :: operator, but then why is it that this version of the code only works when using the :: operator:
#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";
}
This version does not use a function object, but instead just uses target. However, if I try to change ex_count arguments from list<T>::iterator to just T, I get the error:
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)
But it compiles just fine the way I have it written above.
So what causes this?