Topic: tolower conflict
Author: "Gabor Greif" <gabor.greif@no.drsolomon.com>
Date: 1998/10/05 Raw View
On Mon, Oct 5, 1998 9:21 Uhr, Nathan Myers <mailto:ncm@nospam.cantrip.org>
wrote:
>The problem here is that _transform_ is a template, and the compiler
>is supposed to deduce the pointer type from what you passed. The
>compiler really doesn't know which tolower you mean. Given a hint,
>it can figure it out.
>
>
On a similar vein...
Consider this setup:
template <typename T>
int foo(const T&);
template <typename T>
void bar(int (*p)(const T&));
int main()
{
bar(foo<int>); // legal?
bar(&foo<int>); // same as above?
bar(static_cast<int (*)(const int&)>(&foo)); // only legal way without
another variable?
}
This is a very similar problem, that also appears with the CW Pro4
compiler. Support says, that the first two lines of main are illegal by the
standard. I doubt it (not being an expert:-), since the additional hint is
present by explicit parametrisation. Can someone provide some definitive
argument for either point?
Thanks,
Gabor
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/10/08 Raw View
On 05 Oct 98 13:20:46 GMT, Gabor Greif <gabor.greif@no.drsolomon.com> wrote:
>template <typename T> int foo(const T&);
>template <typename T> void bar(int (*p)(const T&));
>int main()
>{
> bar(foo<int>); // legal?
> bar(&foo<int>); // same as above?
> bar(static_cast<int (*)(const int&)>(&foo));
>}
[13.4 Address of overloaded function] [over.over] [item 2]
If the name is a function template, template argument deduction (14.8.2.2),
and if the argument deduction succeeds, the deduced template arguments are
used to generate a single template function, which is added to the set of
overloaded functions considered.
Nothing is said of whether you can explicitly specify a function template
using <...> when you want to take the address of the template function.
When calling functions, you can indeed use the <...>. For example,
foo<double>(3);
This is confirmed in sec 14.8.2.4, item 17. By contrast, this seems to
be illegal:
&foo<double>;
Think about it. It must be illegal. We could have overloaded/templated
functions like this:
template <class T> void foo(T);
template <class T> void foo(T,T);
&foo<double>; // is this: foo<double>(double), or foo<double>(double,double)
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: gurnec@my-dejanews.com
Date: 1998/10/09 Raw View
In article <slrn6vc02a.1kq.sbnaran@localhost.localdomain>,
sbnaran@KILL.uiuc.edu wrote:
> On 05 Oct 98 13:20:46 GMT, Gabor Greif <gabor.greif@no.drsolomon.com> wrote:
>
> >template <typename T> int foo(const T&);
> >template <typename T> void bar(int (*p)(const T&));
>
> >int main()
> >{
> > bar(foo<int>); // legal?
> > bar(&foo<int>); // same as above?
> > bar(static_cast<int (*)(const int&)>(&foo));
> >}
>
> [13.4 Address of overloaded function] [over.over] [item 2]
>
> If the name is a function template, template argument deduction (14.8.2.2),
> and if the argument deduction succeeds, the deduced template arguments are
> used to generate a single template function, which is added to the set of
> overloaded functions considered.
>
> Nothing is said of whether you can explicitly specify a function template
> using <...> when you want to take the address of the template function.
> When calling functions, you can indeed use the <...>. For example,
> foo<double>(3);
> This is confirmed in sec 14.8.2.4, item 17. By contrast, this seems to
> be illegal:
> &foo<double>;
IS 14.8.1:
2. A template argument list may be specified when referring to a
specialization of a function template ... when the address of a function is
taken, ...
All three calls are perfectly valid.
>
> Think about it. It must be illegal. We could have overloaded/templated
> functions like this:
>
> template <class T> void foo(T);
> template <class T> void foo(T,T);
>
> &foo<double>; // is this: foo<double>(double), or foo<double>(double,double)
In this context, it's still ambiguous. However, specifying the template
argument does limit the set of functions that are considered. Given all the
declarations above (one of bar, all three of foo), the following call is
legal:
bar(&foo<double>);
Overload resolution selects "int foo<double>(const double&)" and then "void
bar<double>(int (*)(const double&))" is deduced and then called.
-Chris Gurnee
--
mangled email: gurnec_at_mediaone_dot_net
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sdr@camsoft.com
Date: 1998/10/03 Raw View
Flaw in the standard or in the compiler? You be the judge:
With Metrowerks CodeWarrior Pro 4, the following compiles:
#include <algorithm>
#include <cctype>
void func()
{
char *p;
int n;
std::transform(p, p+n, p, std::tolower);
}
but if you #include <locale> then it doesn't saying Error : function call
'transform(char *, char *, char *, int (int))' does not match
'std::transform(T, T, T, T)' 'std::transform(T, T, T, T, T)'
The response was:
>I'm afraid this is standard behavior. You can get what you want
> with a cast:
>
> std::transform(p, p+n, p, (int (*)(int))std::tolower);
>
>There is a global template method in locale also named tolower. The cast
>disambiguates the situation.
I hate casts. Is this the right answer, or should the compiler be smarter?
There's probably a gobbledygook involving the templatized version in <locale>
together with mem_fun and bind2nd and who knows what but I can't figure out
how to use it. When I do, I'll write string tolower(const string &); and
forget about it. If someone else wants to have a crack at template<class T>
basic_string<T> tolower(const basic_string<T> &, std::locale &); or whatever
the right, totally general version should be, then go to it.
-Stew
sdr@camsoft.com
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/10/05 Raw View
On 03 Oct 98 14:08:17 GMT, sdr@camsoft.com <sdr@camsoft.com> wrote:
>Flaw in the standard or in the compiler? You be the judge:
> std::transform(p, p+n, p, std::tolower);
This works on both my compilers whether or not <locale> is included.
>I hate casts. Is this the right answer, or should the compiler be smarter?
Yes, casts are almost always bad programming style.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/10/05 Raw View
<sdr@camsoft.com> wrote:
>Flaw in the standard or in the compiler? You be the judge:
>
>#include <algorithm>
>#include <cctype>
>void func() { char *p; int n; std::transform(p, p+n, p, std::tolower); }
>
>but if you #include <locale> then it doesn't ...
>
>The response was:
>
>>I'm afraid this is standard behavior. You can get what you want
>> with a cast:
>>
>> std::transform(p, p+n, p, (int (*)(int))std::tolower);
>>
>>There is a global template method in locale also named tolower. The cast
>>disambiguates the situation.
>
>I hate casts. Is this the right answer, or should the compiler be smarter?
MW's answer is correct as far as it goes. I hate casts too; you will
be happy to learn that a cast is not necessary. This should work:
int (* pf)(int) = std::tolower;
std::transform(p, p+n, p, pf);
>There's probably a gobbledygook involving the templatized version in
><locale> together with mem_fun and bind2nd and who knows what but I
>can't figure out how to use it.
It's not that tolower is a template, it's that it's an overloaded function.
Taking the address of an overloaded function is a little bit tricky, but
this is nothing new. It was the same in Cfront, IIRC.
The problem here is that _transform_ is a template, and the compiler
is supposed to deduce the pointer type from what you passed. The
compiler really doesn't know which tolower you mean. Given a hint,
it can figure it out.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]