Reputation: 338
I'm requested to implement a simple algorithm which returns a set. It recevies a container (of stl) and an object which implements the binary () opertor. This operator receives two containers and returns a boolean. The returned set will contain every element of the original container which follows some rules. So my algo looks like this:
template<typename Container, typename T, typename Object>
std::set<T> algo(Container<T>& con, Object obj) {
std::set<T> out;
std::vector<T> one;
std::vector<T> two;
bool flag_passed_x = false;
for (typename Container::iterator i = con.begin(); i != con.end(); ++i) {
one.clear();
two.clear();
for (typename Container::iterator j = con.begin(); j != con.end();
++j) {
// split the container
if (i == j)
flag_passed_x = true;
if (!flag_passed_x)
one.insert(*j);
else
two.insert(*j);
}
if (obj(one, two)) {
out.insert(*i);
}
}
return out;
}
I also tried the implement a test, by creating the class Kuku whic implements the operator () and send a vector to that algorithm which contains the numbers 0-9.
template<typename Container>
class Kuku {
bool operator()(const Container& low, const Container& high) {
for(typename Container::iterator i = low.begin(); i != low.end(); ++i) {
for(typename Container::iterator j = high.begin(); j != high.end(); ++j) {
if ((int) *j > (int) *i)
return false;
}
}
return true;
}
};
Tried to call it with:
int main(){
std::vector<int> v;
Kuku<std::vector<int>> kik;
for (int i = 0; i < 10; i++)
v.push_back(i);
line 58 ---> std::set<int> a = algo(v, kik);
return 0;
}
but I'm getting errors that I can't get rid of:
Description Resource Path Location Type
no matching function for call to 'algo(std::vector<int>&, Kuku<std::vector<int> >&)' a.cpp /dry4 line 58 C/C++ Problem
Description Resource Path Location Type
Invalid arguments '
Candidates are:
std::set<#1,std::less<#1>,std::allocator<#1>> algo(#0 &, #2)
' a.cpp /dry4 line 58 Semantic Error
Upvotes: 2
Views: 1221
Reputation: 41092
Your code is riddled with errors
You neglected to mention the first error you actually get:
error: 'Container' is not a template
std::set<T> algo(Container<T>& con, Object obj)
You can fix this by modifying your template arguments:
template<template<class...> class Container, typename T, typename Object>
std::set<T> algo(Container<T>& con, Object obj) {
Next, you try to insert
into vectors
with a value. Use push_back
instead:
if (!flag_passed_x)
one.push_back(*j);
else
two.push_back(*j);
Next, you have an incomplete iterator declaration for your Container
. You need to qualify it as Container<T>::iterator
for (typename Container<T>::iterator i = con.begin(); i != con.end(); ++i) {
// ...
for (typename Container<T>::iterator j = con.begin(); j != con.end();
Next, you don't expose Kuku
's operator()
as public:
template<typename Container>
class Kuku {
public:
bool operator()
Next, you inadvertently try to get a normal iterator from a const
container instead of a const_iterator
:
for(typename Container::const_iterator i = low.begin(); i != low.end(); ++i) {
for(typename Container::const_iterator j = high.begin(); j != high.end(); ++j) {
Upvotes: 2
Reputation: 28987
I think your problem is:
template<typename Container, typename T, typename Object>
std::set<T> algo(Container<T>& con, Object obj) {
It should be:
template<typename Container, typename T, typename Object>
std::set<T> algo(Container& con, Object obj) {
Don't try and make Container
be a class-template (and that is not how you declare class templates as arguments anyway). Just let it be a simple class (which may well be generated from a template). The particular problem is that std::vector
doesn't have a single template argument - it has at least two (T and allocator), and (at least in older versions of C++) there may be implementation specific additional parameters. (I don't know whether they removed that in later versions of the standard.)
If you really want to make Container
be a class template, then it needs to be:
template<
template<typename T1, class Allocator = std::allocator<T1>> typename Container,
typename T,
typename Object>
std::set<T> algo(Container<T>& con, Object obj) {
Incidentally, I think your loop could be simplified to:
for (auto i = con.begin(); i != con.end(); ++i) {
const std::vector<T> one(con.begin(), i);
const std::vector<T> two(i, con.end());
if (obj(one, two)) {
out.insert(*i);
}
}
Upvotes: 1