I'm trying to write an algorithm that should work with different containers (std::vector, QVector) containing the same type:
template<class Container>
boolean findpeaks(cv::Mat &m, Container<std::pair<int, double>> &peaks) {
// do stuff
peaks.push_back(std::make_pair(1, 1.0));
return true;
}
This one gives me
'Container' is not a template
template<template<typename> class Container>
I get:
error: no matching function for call to 'findpeaks(cv::MatExpr, std::vector >&)'
...
note: template argument deduction/substitution failed:
error: wrong number of template arguments (2, should be 1)
Calling code:
cv::Mat m(data, true);
std::vector<std::pair<int, double>> peaks;
QVERIFY(daf::findpeaks(m.t(), peaks));
I've also tried something like this:
template<template< template<typename, typename> typename > class Container>
warning: ISO C++ forbids typename key in template template parameter; use -std=c++1z or -std=gnu++1z [-Wpedantic]
And some more errors...
Just as expressed with @Barry's answer, I don't think you need a template template parameter here.
However, you seem to have concern about expressing "a container that supports push_back
with a pair of..."
I suggest you to express this constraint in a sfinae constraint expression instead. Even if your parameter is explicitly requiring std::pair
to be in the first template parameter of a class, it doesn't mean it has a push_back
function, and doesn't mean the supposedly existing push_back
is taking a std::pair
as parameter.
Arguments of a function is currently a bad way of expressing what a template type should be able to do, or should be. You'll have to wait for concepts for that.
In the meantime, you can use a sfinae constraint in your function signature that explicitly express that you need a type that has a member push_back
function that accept a std::pair
:
template<class Container>
auto findpeaks(cv::Mat &m, Container& peaks)
// Using trailing return type
-> first_t<bool, decltype(peaks.push_back(std::make_pair(1, 1.0)))>
// Here's the constraint -^ that expression need to be valid
{
// do stuff
peaks.push_back(std::make_pair(1, 1.0));
return true;
}
first_t
can be implemented that way:
template<typename T, typename...>
using first_t = T;
For the function to exist, the expression inside the decltype
must be valid. If the contraint is not satified, the compiler will try other overloads of the function findpeaks
.