Re: template no-match
In article <1163534340.976255.271780@f16g2000cwb.googlegroups.com>,
Maitre Bart <maitrebart@excite.com> wrote:
I made a functor that outputs a custom-formatted string given a pair as
input:
class pair2string
{
public:
pair2string() : _sep(" => ") {}
pair2string(const string& sep_) : _sep(sep_) {}
template <typename F, typename S>
string operator()(pair<F,S>& p_) const
{
ostringstream oss;
oss << p_.first << _sep << p_.second;
return oss.str();
}
private:
const string _sep;
};
It works fine for:
cout << pair2string()(*m.begin()) << "\n";
where m is a map<string,int> .
But if one of the pair arguments is a pair, there is a no-match, as
for:
cout << pair2string()(make_pair("test",*m.begin())) << "\n";
So, I tried to add this overload in my class to solve the no-match:
template <typename F, typename SF, typename SS>
string operator()(pair<F,pair<SF,SS> >& p_) const
{
ostringstream oss;
oss << p_.first << _sep << pair2string(_sep)(p_.second);
return oss.str();
}
But I still get a no-match from the compiler. Anyone has any idea why
and have a solution to the no-match?
In the end, I'd like to overload the 2 other possibilities:
template <typename FF, typename FS>
string operator()(pair<pair<FF,FS>,S>& p_) const
{
ostringstream oss;
oss << pair2string(_sep)(p_.first) << _sep << p_.second;
return oss.str();
}
template <typename FF, typename FS, typename SF, typename SS>
string operator()(pair<pair<FF,FS>,pair<SF,SS> >& p_) const
{
ostringstream oss;
oss << pair2string(_sep)(p_.first) << _sep <<
pair2string(_sep)(p_.second);
return oss.str();
}
Thank you for helping me.
we must determine which if any of the members of the pair is another
pair. To do this I wrote these simple templates;
template <bool B> struct bool_{};
typedef bool_<true> true_;
typedef bool _<false> false_;
template <typename T> struct is_pair{static const bool value = false;};
template <typename T,typename U> struct is_pair<std::pair<T,U> >
{ static const bool value = true;};
now let operator () (std::pair<T,U> const &p) call an overloaded private
member for each of the four possibilities as shown below. if the
argument of the pair is a pair call operator () recursively else just
use it.
This compiled with CW 10 and runs correctly.
#include <utility>
#include <string>
#include <sstream>
#include <iostream>
template <bool B> struct bool_{};
typedef bool_<true> true_;
typedef bool_<false> false_;
template <typename T>
struct is_pair {static const bool value = false;};
template <typename T,typename U>
struct is_pair<std::pair<T,U> >
{ static const bool value = true;};
class pair2string
{
const std::string sep;
template <class T,class U>
std::string do_it(std::pair<T,U> const &p,false_,false_)
{
std::ostringstream oss;
oss << p.first << sep << p.second ;
return oss.str();
}
template <class T,class U>
std::string do_it(std::pair<T,U> const &p,false_,true_)
{
std::ostringstream oss;
oss << p.first << sep << (this->operator()(p.second));
return oss.str();
}
template <class T,class U>
std::string do_it(std::pair<T,U> const &p,true_,false_)
{
std::ostringstream oss;
oss << (this->operator())(p.first) << sep << p.second;
return oss.str();
}
template <class T,class U>
std::string do_it(std::pair<T,U> const &p,true_,true_)
{
std::ostringstream oss;
oss << (this->operator())(p.first) << sep <<
(this->operator())(p.second);
return oss.str();
}
public:
explicit pair2string(const std::string &a="->")
:sep(a){}
template <class T,class U>
std::string operator () (std::pair<T,U> const &p)
{
return this->do_it
(
p,
bool_<is_pair<T>::value>(),
bool_<is_pair<U>::value>()
);
}
};
int main()
{
pair2string flatten;
std::cout << flatten(std::make_pair(1,2)) << '\n';
std::cout << flatten(std::make_pair(1,std::make_pair(2,3))) << '\n';
std::cout << flatten(std::make_pair(std::make_pair(1,2),3)) << '\n';
std::cout <<
flatten(std::make_pair(std::make_pair(1,2),std::make_pair(3,4))) <<
'\n';
std::cout << flatten
(std::make_pair(std::make_pair(std::make_pair(1,2),3),std::make_pair(4,5)
)) << '\n';
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]