libstdc++/5133: Problems with toupper
Christopher Currie
christopher@currie.com
Thu Jun 27 23:20:00 GMT 2002
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p
r=5133
Sorry to dig up this old PR, but it seems to still be in feedback state, and
I've been working with the problem recently and I wanted to weigh in.
Philip Martin wrote:
> using the function template is
> tricky because the second parameter is a reference. One would like to
> try
>
> // this won't work
> std::locale loc;
> std::transform(s.begin(),s.end().s.begin(),
> std::bind2nd(std::ptr_fun(std::tolower<char>),loc));
>
> but this will suffer from the reference to a reference problem.
Without going into too much detail, the problem is detected in binder2nd's
constructor, but can be traced to the definition of the binary_function
template. I was able to get the above code working by adding a
specialization of the template, used when the second argument is a
reference:
#include <functional>
#include <algorithm>
#include <string>
#include <locale>
namespace std
{
// specialization for the second argument being a reference
template <class _Arg1, class _Arg2, class _Result>
struct binary_function<_Arg1, _Arg2&, _Result> {
typedef _Arg1 first_argument_type;
typedef _Arg2 second_argument_type;
typedef _Result result_type;
};
}
int main()
{
using namespace std;
string s ("Someone Chanted Evening");
locale loc;
transform(s.begin(), s.end(), s.begin(),
bind2nd(ptr_fun(&tolower<char>), loc));
return 0;
}
Naturally, a second specialization would be necessary for the first
argument, so that bind1st will also behave as expected.
The remaining questions: Does this specialization violate the Standard,
and/or will it break existing code?
Comments and criticisms welcome.
Christopher Currie
More information about the Gcc-bugs
mailing list