I have a class template. Within this class template, I am trying to define a member function template which accepts const_iterators on a collection of strings. The collection itself can be any kind of StdLib collection, but realistically it will be either a vector or a list.
Since the collection can be any type, I am using a template-template parameter to specify the collection type. However it will always be a collection of string. I want template argument deduction to work so that I don't have to specify the collection type when calling the member function.
The code that follows in an SSCCE that resembles my intended use-case.
So far, I have for the class definition (Live Demo):
template <typename Foo>
struct Gizmo
{
Foo mF;
Gizmo (Foo f) : mF (f) {};
template <template <typename> class Cont> void DoIt(
typename Cont <string>::const_iterator begin,
typename Cont <string>::const_iterator end)
{
stringstream ss;
ss << "(" << this->mF << ")\n";
const std::string s = ss.str();
copy (begin, end, ostream_iterator <std::string> (cout, s.c_str()));
}
};
Compilation of instantiation of the class template succeeds:
int main()
{
list <string> l;
l.push_back ("Hello");
l.push_back ("world");
Gizmo <unsigned> g (42);
}
However when I try to leverage argument deduction (without which, this whole exercise is almost pointless):
g.DoIt (l.begin(), l.end());
GCC complains that it can't deduce the template argument:
prog.cpp: In function ‘int main()’:
prog.cpp:34:28: error: no matching function for call to ‘Gizmo<unsigned int>::DoIt(std::list<std::basic_string<char> >::iterator, std::list<std::basic_string<char> >::iterator)’
g.DoIt (l.begin(), l.end());
^
prog.cpp:34:28: note: candidate is:
prog.cpp:16:49: note: template<template<class> class typedef Cont Cont> void Gizmo<Foo>::DoIt(typename Cont<std::basic_string<char> >::const_iterator, typename Cont<std::basic_string<char> >::const_iterator) [with Cont = Cont; Foo = unsigned int]
template <template <typename> class Cont> void DoIt(
^
prog.cpp:16:49: note: template argument deduction/substitution failed:
prog.cpp:34:28: note: couldn't deduce template parameter ‘template<class> class typedef Cont Cont’
g.DoIt (l.begin(), l.end());
Ultimately all I really care about is being able to call DoIt with begin and end iterators on a collection of string. The actual type of collection can either be vector or list, and I don't want to have to either specify the template arguments, nor do I want to overload based on container.
How can I get this to work?
Note that my actual use-case will be in C++03. C++11 solutions are welcomed, but I'll only be able to accept a C++03 solution.
vectoris not a type. Onlyvector <string>is. Make sense? - John Dibling