t.C:122: error: No match for 'fmap(list<list<int> > &, char(&)(int))'
t.C:126: error: No match for 'fmap(list<list<int> > &, int(&)(int))'
t.C:130: error: No match for 'fmap(list<list<list<int> > > &,
int(&)(int))'
...for the first error, it seems like it should be able to match my #1
by instantiating...
In = list
Out = list
T = int
U = char
...Or maybe you can provide a link to other people working on polytypic
programming in C++? (You can look at a syntax highlighted version of
the code at... http://sleepingsquirrel.org/cpp/test_fmap.cpp.html )
Thanks,
Greg Buchholz
*/
#include<iostream>
#include<list>
#include<algorithm>
#include<functional>
#include<iterator>
#define REC_No_2_3 //undef to comment out extra code that I think
//shouldn't be needed.
using namespace std;
//Base Case: No further calls to "fmap"
template<template<class> class In, class T, class U>
In<U> fmap(In<T> i, U (*f)(T))
{
In<U> temp;
transform(i.begin(),i.end(),back_inserter(temp),f);
return temp;
}
//Recursive Case #1: Should be used with nested lists
template<template<class>class In, template<class> class Out, class T,
class U>
list<Out<U> > fmap(list<In<T> > l, U (*f)(T))
{
list<Out<U> > temp;
// Using "transform" doesn't work, complaining of unresolved
overloading
// of bind2nd...
// transform(l.begin(),l.end(),back_inserter(temp),
bind2nd(fmap,f));
// return temp;
for(typename list<In<T> >::const_iterator iter = l.begin();
iter != l.end(); ++iter)
{
temp.push_back(fmap(*iter,f));
}
return temp;
}
#ifdef REC_No_2_3
//Recursive Case #2: Note that the output data structure has to be the
// same as the input data structure.
template<class In, class Func> list<list<In> > fmap(list<list<In> > l,
Func f)
{
list<list<In> > temp;
for(typename list<list<In> >::const_iterator iter = l.begin();
iter != l.end(); ++iter)
{
temp.push_back(fmap(*iter,f));
}
return temp;
}
//Recursive Case #3: Seems like the problem here is that "Out" doesn't
// depend on "In", so "Out" has to be manually
specified.
template<class In, class Out, class Func>
list<list<Out> > fmap(list<list<In> > l, Func f)
{
list<list<Out> > temp;
for(typename list<list<In> >::const_iterator iter = l.begin();
iter != l.end(); ++iter)
{
temp.push_back(fmap(*iter,f));
}
return temp;
}
#endif
int lsize(list<int> l) //compute number of elements in a list
{
int size = 0;
for(list<int>::const_iterator i = l.begin(); i!= l.end(); ++i)
size++;
return size;
}
int inc(int x){ return x+1; }
char to_char(int x){ return 'A'+(char)x; }
template<class T> std::ostream& operator<<(std::ostream&, const
std::list<T>&);
int main(int argc, char* argv[])
{
int tmp[] = {1,2,3};
list<int> simple_list(tmp,tmp+3);
list<list<int> > lol;
lol.push_back(simple_list);
lol.push_back(simple_list);
cout << "to_char of simple list: " << simple_list << " => "
<< fmap(simple_list,to_char) << endl;
#ifndef REC_No_2_3
cout << "lol = " << lol << endl
<< "lengths of lol's lists = " << fmap(lol,lsize) << endl;
#endif
//This example uses Recursive #3.
cout << "to_char of lol: "<< lol << " => "
<< fmap<int,char>(lol,to_char) << endl;
//The next two "fmap"s use Recursive #2.
cout << " inc of lol: "<< lol << " => "
<< fmap(lol,inc) << endl;
list<list<list<int> > > lolol;
lolol.push_back(lol);
cout << " inc of lolol: "<< lolol << " => " << fmap(lolol,inc) <<
endl;
//And I haven't yet got this to work...
//cout << "to_char of lolol: "<< lolol << " => "
// << fmap(lolol,to_char) << endl;
return 0;
}
template<class T> std::ostream& operator<<(std::ostream& o, const
std::list<T>& l)
{
o << "[";
for(typename std::list<T>::const_iterator i = l.begin(); i !=
--l.end(); ++i)
o << *i << ",";
return o << *(--l.end()) << "]";
}
fmap<list<list>,list<list> >(lolol,inc)
...isn't proper syntax. My compiler (g++) complains...
t.C:113: error: type/value mismatch at argument 1 in template parameter
list for 'template<class _Tp, class _Alloc> class list'
t.C:113: error: expected a type, got 'list'
t.C:113: error: template argument 2 is invalid
t.C:113: error: type/value mismatch at argument 1 in template parameter
list for 'template<class _Tp, class _Alloc> class list'
t.C:113: error: expected a type, got 'list'
t.C:113: error: template argument 2 is invalid
t.C:113: error: No match for 'fmap(list<list<list<int> > > &, int
(&)(int))'
...And I'd appreciate any tips or hints on changes I could make to the
code in order to help the compiler deduce the template parameters
without having to manually specify them.
Thanks,
Greg Buchholz
*/
#include<iostream>
#include<list>
#include<algorithm>
#include<functional>
#include<iterator>
#define PROBLEM_AREA //undef to comment out problem areas and
//successfully compile the rest of program.
using namespace std;
//Base Case: No further calls to "fmap"
template<template<class> class In, class T, class U>
In<U> fmap(In<T> i, U (*f)(T))
{
In<U> temp;
transform(i.begin(),i.end(),back_inserter(temp),f);
return temp;
}
//Recursive Case #1: Should be used with nested lists
template<template<class> class In, template<class> class Out, class T,
class U>
list<In<U> > fmap(list<In<T> > l, U (*f)(T))
{
list<In<U> > temp;
for(typename list<In<T> >::const_iterator iter = l.begin();
iter != l.end(); ++iter)
{
temp.push_back(fmap(*iter,f));
}
return temp;
}
int lsize(list<int> l) //compute number of elements in a list
{
int size = 0;
for(list<int>::const_iterator i = l.begin(); i!= l.end(); ++i)
size++;
return size;
}
int inc(int x){ return x+1; }
char to_char(int x){ return 'A'+(char)x; }
template<class T> std::ostream& operator<<(std::ostream&, const
std::list<T>&);
int main(int argc, char* argv[])
{
int tmp[] = {1,2,3};
list<int> simple_list(tmp,tmp+3);
list<list<int> > lol;
lol.push_back(simple_list);
lol.push_back(simple_list);
cout << "to_char of simple list: " << simple_list << " => "
<< fmap(simple_list,to_char) << endl;
cout << "lol = " << lol << endl
<< "lengths of lol's lists = " << fmap(lol,lsize) << endl;
cout << "to_char of lol: "<< lol << " => "
<< fmap<list,list,int,char>(lol,to_char) << endl;
cout << " inc of lol: "<< lol << " => "
<< fmap<list,list>(lol,inc) << endl;
list<list<list<int> > > lolol;
lolol.push_back(lol);
/* How do you tell the compiler that the template parameters
are lists of lists? */
#ifdef PROBLEM_AREA
cout << " inc of lolol: "<< lolol << " => "
<< fmap<list<list>,list<list> >(lolol,inc) << endl;
cout << "to_char of lolol: "<< lolol << " => "
<< fmap<list<list>,list<list> >(lolol,to_char) << endl;
#endif
//Base Case: No further calls to "fmap"
template<template<class> class Alloc, template<class, class> class
Container, class T, class U>
Container<U, Alloc<U> > fmap(Container<T, Alloc<T> > i, U (*f)(T))
{
Container<U, Alloc<U> > temp;
transform(i.begin(),i.end(),back_inserter(temp),f);
return temp;
}
//Recursive Case #1: Should be used with nested lists
template<template<class> class Alloc, template<class, class> class
Container, class T, class U>
list<Container<U, Alloc<U> > > fmap(list<Container<T, Alloc<T> > > l, U
(*f)(T))
{
list<Container<U, Alloc<U> > > temp;
for(typename list<Container<T, Alloc<T> > >::const_iterator iter =
l.begin();
iter != l.end(); ++iter)
{
temp.push_back(fmap(*iter,f));
}
return temp;
}
int lsize(list<int> l) //compute number of elements in a list
{
int size = 0;
for(list<int>::const_iterator i = l.begin(); i!= l.end(); ++i)
size++;
return size;
}
int inc(int x){ return x+1; }
char to_char(int x){ return 'A'+(char)x; }
template<class T> std::ostream& operator<<(std::ostream& o, const
std::list<T>& l)
{
o << "[";
for(typename std::list<T>::const_iterator i = l.begin(); i !=
--l.end(); ++i)
o << *i << ",";
return o << *(--l.end()) << "]";
}
int main(int argc, char* argv[])
{
int tmp[] = {1,2,3};
list<int> simple_list(tmp,tmp+3);
list<list<int> > lol;
lol.push_back(simple_list);
lol.push_back(simple_list);
cout << "to_char of simple list: " << simple_list << " => "
<< fmap(simple_list,to_char) << endl;
cout << "lol = " << lol << endl
<< "lengths of lol's lists = " << fmap(lol,lsize) << endl;
cout << "to_char of lol: "<< lol << " => "
<< fmap(lol,to_char) << endl;
cout << " inc of lol: "<< lol << " => "
<< fmap(lol,inc) << endl;
list<list<list<int> > > lolol;
lolol.push_back(lol);
return 0;
}
you know std::list's declare is
template<class _Ty,
class _Ax = allocator<_Ty> >
class list;
so i add the Alloc to tell complier to deduce the params.
and i change to In to Container.
and
fmap<list<list>,list<list> >(lolol,inc)
...isn't proper syntax. My compiler (g++) complains...
because the function tell the complier wrong infors, so she can not
deduce the right params
so should add somethings likes:
template<typename L>
list<L> incL(list<L>);
cheers!