Problem with <algorithm> transform

Discussion in 'C++' started by Gerald I. Evenden, Jan 6, 2008.

  1. Working on a Kubuntu 64bit system "c++ (GCC) 4.0.3".

    The following simple program extracted from p.497 & 499 of N.M.Josurris'
    "The C++ Standard Library ... " (file t.cpp):

    1 #include <string>
    2 #include <iostream>
    3 #include <algorithm>
    4 #include <cctype>
    5 using namespace std;
    6 int main() {
    7 string s("This is the zip code of Hodna 1223");
    8 cout << "original: " << s <<endl;
    9 transform(s.begin(), s.end(),s.begin(), toupper);
    10 cout << "upper: " << s << endl;
    11 }

    results in the following error output when executing 'c++ t.cpp'

    t.cpp: In function ‘int main()’:
    t.cpp:9: error: no matching function for call
    to ‘transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char,
    std::char_traits<char>, std::allocator<char> > >,
    __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
    std::char_traits<char>, std::allocator<char> > >,
    __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
    std::char_traits<char>, std::allocator<char> > >, <unknown type>)’

    Something seems seriously wrong but I can't figure it.

    Help, suggestions greatly appreciated.
     
    Gerald I. Evenden, Jan 6, 2008
    #1
    1. Advertising

  2. > transform(s.begin(), s.end(),s.begin(), toupper);

    > Something seems seriously wrong but I can't figure it.


    Alas, toupper is a macro so you can't pass it as an argument.
     
    Andrew Koenig, Jan 6, 2008
    #2
    1. Advertising

  3. On 2008-01-06 21:45, Andrew Koenig wrote:
    >> transform(s.begin(), s.end(),s.begin(), toupper);

    >
    >> Something seems seriously wrong but I can't figure it.

    >
    > Alas, toupper is a macro so you can't pass it as an argument.


    Are you sure? In C99 it is a function specified as int toupper(int c)
    (section 7.4.2.2, "The toupper function") and in C++98 table 45 it is
    also listed as a function.

    To the OP: the code you posted compiled and ran fine with MSVC++ so I am
    not sure why it did not work for you. However there is also a toupper()
    function in C++ declared in the <locale> header which might work (i.e.
    replace <cctype> with <locale> and try again).

    --
    Erik Wikström
     
    Erik Wikström, Jan 6, 2008
    #3
  4. Gerald I. Evenden

    Jerry Coffin Guest

    In article <lfagj.804$xA6.524@trndny09>,
    says...
    > Working on a Kubuntu 64bit system "c++ (GCC) 4.0.3".
    >
    > The following simple program extracted from p.497 & 499 of N.M.Josurris'
    > "The C++ Standard Library ... " (file t.cpp):


    [ ... code elided ]

    > results in the following error output when executing 'c++ t.cpp'


    The problem appears to be with your installation of gcc -- the code is
    fine.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Jan 6, 2008
    #4
  5. * Erik Wikström:
    > On 2008-01-06 21:45, Andrew Koenig wrote:
    >>> transform(s.begin(), s.end(),s.begin(), toupper);
    >>> Something seems seriously wrong but I can't figure it.

    >> Alas, toupper is a macro so you can't pass it as an argument.

    >
    > Are you sure? In C99 it is a function specified as int toupper(int c)
    > (section 7.4.2.2, "The toupper function") and in C++98 table 45 it is
    > also listed as a function.


    The reference you give is correct, and means that Andrew Koenig made a
    mistake.


    > To the OP: the code you posted compiled and ran fine with MSVC++ so I am
    > not sure why it did not work for you.


    Ironically, the error seems to be due to Koenig lookup... :)

    However, adding an include of <locale> does not reproduce the error with
    MSVC 7.1.

    As Newton puportedly said, I frame no hypothesis.


    > However there is also a toupper()
    > function in C++ declared in the <locale> header which might work (i.e.
    > replace <cctype> with <locale> and try again).


    No, that one is a bit different: it suffers from the usual standard
    library (except STL parts) unusability and complexity, taking a locale
    argument as second argument.

    A cure for the immediate problem is to write

    ::toupper

    but this may be a compiler-specific cure (I'm not sure).

    However, it doesn't matter much, because using the C library's toupper
    function directly is a big no-no: it should only be used via a wrapper like

    char toUpper( char c )
    {
    return static_cast<char>(
    ::toupper( static_cast<unsigned char>( c ) )
    );
    }

    Otherwise, with negative char value promotion to integer (the formal
    argument) will yield a value that is not representable as unsigned char,
    which the C library toupper function requires.

    So to sum up, the Josuttis book example may be correct for the given
    data (only ASCII characters), but not for an arbitrary input string,
    and, g++ apparently does something funny.

    Cheers, & hth.,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 6, 2008
    #5
  6. Gerald I. Evenden

    Jerry Coffin Guest

    In article <U5bgj.112153$>,
    says...
    > > transform(s.begin(), s.end(),s.begin(), toupper);

    >
    > > Something seems seriously wrong but I can't figure it.

    >
    > Alas, toupper is a macro so you can't pass it as an argument.


    Unless my memory is worse than usual today, a function-like macro is
    only supposed to be expanded when/if its name is followed by an open
    parenthesis, so in this case the fact that there may be a macro by that
    name shouldn't make any difference.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Jan 6, 2008
    #6
  7. Gerald I. Evenden

    James Kanze Guest

    On Jan 6, 9:45 pm, "Andrew Koenig" <> wrote:
    > > transform(s.begin(), s.end(),s.begin(), toupper);
    > > Something seems seriously wrong but I can't figure it.


    > Alas, toupper is a macro so you can't pass it as an argument.


    Comme now, Andy, you know better than that. In C, toupper may
    be a function style macro, but the function declaration must
    also be present (hidden by the macro), and will be used if the
    token immediately following the symbol isn't a '('. In C++,
    toupper is a set of overloaded functions (including a function
    template), and can't be used without some sort of overload
    disambiguation. Typically, this will be the arguments in a
    function call or, when taking the address, the type of the
    destination. The problem here is that where the code takes the
    address matches a templated parameter of a template function.
    Which means that the compiler can't possibly do type deduction,
    and the call fails.

    Of course, the original code couldn't work anyway; it expects to
    call toupper with a single, char argument, and the only overload
    of toupper that can be legally called with a char argument
    requires a locale as the second argument.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 7, 2008
    #7
  8. Gerald I. Evenden

    James Kanze Guest

    On Jan 6, 10:17 pm, Erik Wikström <> wrote:
    > On 2008-01-06 21:45, Andrew Koenig wrote:


    > >> transform(s.begin(), s.end(),s.begin(), toupper);


    > >> Something seems seriously wrong but I can't figure it.


    > > Alas, toupper is a macro so you can't pass it as an argument.


    > Are you sure? In C99 it is a function specified as int toupper(int c)
    > (section 7.4.2.2, "The toupper function") and in C++98 table 45 it is
    > also listed as a function.


    > To the OP: the code you posted compiled and ran fine with
    > MSVC++ so I am not sure why it did not work for you.


    It's undefined behavior, so it might compile. I'd be very
    surprised if it worked correctly with VC++, however (unless you
    compiled with the /J option).

    > However there is also a toupper() function in C++ declared in
    > the <locale> header which might work (i.e. replace <cctype>
    > with <locale> and try again).


    There are two separate issues involved here. The first is that
    in C++, toupper is overloaded, with one of the overloads (the
    one in <locale> being a function template. And that the
    standard allows any standard C++ header to include any other.
    Obviously, if the template function is visible, the compiler
    can't possibly resolve type deduction for std::transform unless
    you somehow tell it which overload you want to use: it's using
    the type of the argument (i.e. the name of the function) to
    deduce the template type of std::transfor, and it needs to know
    the target type to resolve the overload on the name. If
    <locale> hasn't been included (directly or indirectly), on the
    other hand, the only function visible is the one in <cctype>,
    type deduction works, and the code compiles.

    The second problem is that if char is signed (which it is by
    default in VC++), there is no overload of std::toupper which can
    be legally called with just a single char argument: the function
    template in <locale> requires two arguments, and the function in
    <cctype> takes an int in the range [0...UCHAR_MAX] as an
    argument---if char is signed, it can (and often will) have a
    negative value, which results in undefined behavior if it is
    passed to the toupper function in <ctype>. This error is so
    common that a number of implementations today actually make the
    code work anyway. For all values except EOF (which is almost
    always -1). (If you're using ISO 8859-1---one of the more
    widespread single byte encoding---then -1 from a char would
    correspond to a 'ÿ', a latin small letter y with diaeresis. And
    ISO 8859-1 doesn't contain a latin capital letter y with
    diaeresis, so returning the same value is correct.)

    Finally, of course, you might even have to ask if any of the
    standard toupper functions are applicable. There is not,
    generally, a one to one mapping of lower to upper, and some
    lower case characters might map to a two character sequence in
    upper case (German 'ß' becomes "SS", or in some special
    contexts, "SZ"; Swiss German 'ä' becomes either "Ae" or "AE",
    etc.). And of course, toupper (in all its forms) is totally
    useless if you have a multibyte encoding, like UTF-8 (which is
    the default, I believe, in most modern Linux distributions).
    Depending on the application, such issues may or may not be
    relevant.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 7, 2008
    #8
  9. Gerald I. Evenden

    James Kanze Guest

    On Jan 6, 11:15 pm, "Alf P. Steinbach" <> wrote:
    > * Erik Wikström:


    > > On 2008-01-06 21:45, Andrew Koenig wrote:
    > >>> transform(s.begin(), s.end(),s.begin(), toupper);
    > >>> Something seems seriously wrong but I can't figure it.
    > >> Alas, toupper is a macro so you can't pass it as an argument.


    > > Are you sure? In C99 it is a function specified as int
    > > toupper(int c) (section 7.4.2.2, "The toupper function") and
    > > in C++98 table 45 it is also listed as a function.


    > The reference you give is correct, and means that Andrew
    > Koenig made a mistake.


    Surprisingly.

    > > To the OP: the code you posted compiled and ran fine with
    > > MSVC++ so I am not sure why it did not work for you.


    > Ironically, the error seems to be due to Koenig lookup... :)


    Not really, but see my other postings.

    > However, adding an include of <locale> does not reproduce the
    > error with MSVC 7.1.


    Are you kidding? (I just tried it with VC++ 8, and I get the
    same results. Could it be that Dinkumware uses some form of
    concept checking to exclude functions here which can't be called
    with only one argument? Or?)

    I haven't tried it, but he did have a "using namespace std;" in
    there, so everything in <locale> should be visible. In theory
    at least---and probably in practice, including <ctype.h> (*NOT*
    <cctype>), and specifying ::toupper (to block any chance of
    finding the functions in <locale>) should allow the code to
    compile.

    > As Newton puportedly said, I frame no hypothesis.


    > > However there is also a toupper() function in C++ declared
    > > in the <locale> header which might work (i.e. replace
    > > <cctype> with <locale> and try again).


    > No, that one is a bit different: it suffers from the usual
    > standard library (except STL parts) unusability and
    > complexity, taking a locale argument as second argument.


    Which is not a problem for occasional use.

    What you really need is some sort of functional object, however,
    which will get the ctype facet once from the locale, and use the
    toupper of the facet.

    > A cure for the immediate problem is to write


    > ::toupper


    > but this may be a compiler-specific cure (I'm not sure).


    If he includes <ctype.h>, the resulting code is guaranteed to
    compile.

    [...]
    > So to sum up, the Josuttis book example may be correct for the
    > given data (only ASCII characters), but not for an arbitrary
    > input string, and, g++ apparently does something funny.


    One of the C++ headers he's included probably includes <locale>
    in the g++ implementation. The standard clearly says that this
    is unspecified (even though it can cause no number of
    portability problems).

    Anyway, I'd be very interested in hearing from someone familiar
    with the VC++ implementation, explaining why the original code
    still compiles when you include <locale>. Like you, I can't
    explain it.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 7, 2008
    #9
  10. Gerald I. Evenden

    James Kanze Guest

    On Jan 6, 11:08 pm, Jerry Coffin <> wrote:
    > In article <lfagj.804$xA6.524@trndny09>,
    > says...


    > > Working on a Kubuntu 64bit system "c++ (GCC) 4.0.3".


    > > The following simple program extracted from p.497 & 499 of N.M.Josurris'
    > > "The C++ Standard Library ... " (file t.cpp):


    > [ ... code elided ]


    > > results in the following error output when executing 'c++ t.cpp'


    > The problem appears to be with your installation of gcc -- the
    > code is fine.


    No it's not. Whether is will compiler or not is unspecified:
    any C++ header may include any other, and if <locale> is
    included, you should have a serious problem with template type
    deduction for the call to std::transform. (From experience, g++
    headers tend to include the world; when you develope under g++,
    then port to other compilers, you very quickly get used to
    having to add includes for headers you'd forgotten.)

    Of course, even if it compiles, it has undefined behavior if
    char is signed.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 7, 2008
    #10
  11. Digging through Prada's "C++ Primer Plus" (5th) I found notes on
    p.936-7 relating to C library functions delared as having int returns
    and problems thereof, so I added a line to t.cpp and changed line
    13's function name:

    1 #include <string>
    2 #include <iostream>
    3 #include <algorithm>
    4 #include <cctype>
    5 using namespace std;
    6 /* I added the following line because cctype
    7 * apparently declares 'int toupper(char)'
    8 */
    9 static char toUpper(char c) { return toupper(c); }
    10 int main() {
    11 string s("This is the zip code of Hodna 1223");
    12 cout << "original: " << s <<endl;
    13 transform(s.begin(), s.end(),s.begin(), toUpper);
    14 cout << "upper: " << s << endl;
    15 }

    then:
    gie@charon:~/Letters/src$ g++ t.cpp
    gie@charon:~/Letters/src$ ./a.out
    original: This is the zip code of Hodna 1223
    upper: THIS IS THE ZIP CODE OF HODNA 1223
    gie@charon:~/Letters/src$
    Problem solved.
    Thanks for the help. This looks like a pop quiz but I did not
    mean it that way.
     
    Gerald I. Evenden, Jan 7, 2008
    #11
  12. Gerald I. Evenden

    James Kanze Guest

    On Jan 7, 4:03 pm, "Gerald I. Evenden" <>
    wrote:
    > Digging through Prada's "C++ Primer Plus" (5th) I found notes
    > on p.936-7 relating to C library functions delared as having
    > int returns and problems thereof, so I added a line to t.cpp
    > and changed line 13's function name:
    >
    > 1 #include <string>
    > 2 #include <iostream>
    > 3 #include <algorithm>
    > 4 #include <cctype>
    > 5 using namespace std;
    > 6 /* I added the following line because cctype
    > 7 * apparently declares 'int toupper(char)'
    > 8 */


    It had better be: "int std::toupper( int )".

    > 9 static char toUpper(char c) { return toupper(c); }


    return toupper( static_cast< unsigned char >( c ) ) ;

    It's undefined behavior to call the std::toupper( int ) above
    with any negative value other than EOF, and char is often
    signed.

    > 10 int main() {
    > 11 string s("This is the zip code of Hodna 1223");
    > 12 cout << "original: " << s <<endl;
    > 13 transform(s.begin(), s.end(),s.begin(), toUpper);
    > 14 cout << "upper: " << s << endl;
    > 15 }


    > then:
    > gie@charon:~/Letters/src$ g++ t.cpp
    > gie@charon:~/Letters/src$ ./a.out
    > original: This is the zip code of Hodna 1223
    > upper: THIS IS THE ZIP CODE OF HODNA 1223
    > gie@charon:~/Letters/src$
    > Problem solved.


    If all the code has to handle is this one string, then there are
    much, much easier ways to do it. In general, the above code has
    undefined behavior.

    And of course, the reason why the code now compiles is because
    there is only one isUpper function, so overload resolution has
    no problem choosing.

    --
    James Kanze (GABI Software) mailto:
    Conseils en informatique orient�e objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 7, 2008
    #12
  13. James Kanze wrote:

    > On Jan 7, 4:03 pm, "Gerald I. Evenden" <>
    > wrote:
    >> Digging through Prada's "C++ Primer Plus" (5th) I found notes
    >> on p.936-7 relating to C library functions delared as having
    >> int returns and problems thereof, so I added a line to t.cpp
    >> and changed line 13's function name:
    >>
    >> 1 #include <string>
    >> 2 #include <iostream>
    >> 3 #include <algorithm>
    >> 4 #include <cctype>
    >> 5 using namespace std;
    >> 6 /* I added the following line because cctype
    >> 7 * apparently declares 'int toupper(char)'
    >> 8 */

    >
    > It had better be: "int std::toupper( int )".


    Yes:

    static int toUpper(int c) { return toupper(c); }

    Works. This seems to negate Prada's argument about type problems.
    Also
    transform(s.begin(), s.end(),s.begin(), ::toupper);
    seems to work (also dropping the toUpper line):

    Alas!! Too much Greek. Note "std::toupper" does NOT work.

    >> 9 static char toUpper(char c) { return toupper(c); }

    >
    > return toupper( static_cast< unsigned char >( c ) ) ;
    >
    > It's undefined behavior to call the std::toupper( int ) above
    > with any negative value other than EOF, and char is often
    > signed.
    >
    >> 10 int main() {
    >> 11 string s("This is the zip code of Hodna 1223");
    >> 12 cout << "original: " << s <<endl;
    >> 13 transform(s.begin(), s.end(),s.begin(), toUpper);
    >> 14 cout << "upper: " << s << endl;
    >> 15 }

    >
    >> then:
    >> gie@charon:~/Letters/src$ g++ t.cpp
    >> gie@charon:~/Letters/src$ ./a.out
    >> original: This is the zip code of Hodna 1223
    >> upper: THIS IS THE ZIP CODE OF HODNA 1223
    >> gie@charon:~/Letters/src$
    >> Problem solved.

    >
    > If all the code has to handle is this one string, then there are
    > much, much easier ways to do it. In general, the above code has
    > undefined behavior.


    Outside of resorting to C char types what would be the efficient
    alternative? The above looks more nifty than what I would have
    to do in straight C.

    > And of course, the reason why the code now compiles is because
    > there is only one isUpper function, so overload resolution has
    > no problem choosing.


    First, I am a total C++ dumbkopf and only an old time C user that
    likes to take advantages of some of C++ notational short cuts.
    In this case I do not see where the overloading of toupper is coming
    from. From what you say it seems to imply that there are multiple
    declarations of toupper---where?? I have only seen toupper used
    in this basic example and each referred to cctype which I assumed
    contained the *only* definition.

    Thanks for your comments. They sparked me to look a little further.
    > --
    > James Kanze (GABI Software) mailto:
    > Conseils en informatique orient�e objet/
    > Beratung in objektorientierter Datenverarbeitung
    > 9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
     
    Gerald I. Evenden, Jan 7, 2008
    #13
  14. Gerald I. Evenden

    James Kanze Guest

    On Jan 7, 7:28 pm, "Gerald I. Evenden" <>
    wrote:
    > James Kanze wrote:
    > > On Jan 7, 4:03 pm, "Gerald I. Evenden" <>
    > > wrote:
    > >> Digging through Prada's "C++ Primer Plus" (5th) I found notes
    > >> on p.936-7 relating to C library functions delared as having
    > >> int returns and problems thereof, so I added a line to t.cpp
    > >> and changed line 13's function name:

    >
    > >> 1 #include <string>
    > >> 2 #include <iostream>
    > >> 3 #include <algorithm>
    > >> 4 #include <cctype>
    > >> 5 using namespace std;
    > >> 6 /* I added the following line because cctype
    > >> 7 * apparently declares 'int toupper(char)'
    > >> 8 */


    > > It had better be: "int std::toupper( int )".


    > Yes:


    > static int toUpper(int c) { return toupper(c); }


    > Works. This seems to negate Prada's argument about type problems.


    The "type problem" is that the compiler cannot deduce the type
    to instantiate std::transform.

    > Also
    > transform(s.begin(), s.end(),s.begin(), ::toupper);
    > seems to work (also dropping the toUpper line):


    As it should---*if* you include <ctype.h>, rather than <cctype>.
    According to the standard, it shouldn't work if you only include
    <cctype>, but in practice, it will with most, if not all,
    implementations, and the standard has been (or will be) modified
    to allow (but not require) it to work with <cctype>.

    > Alas!! Too much Greek. Note "std::toupper" does NOT work.


    Again, with the includes above, its unspecified whether it works
    or not. With an explicit include of <locale>, it shouldn't
    work.

    > >> 9 static char toUpper(char c) { return toupper(c); }


    > > return toupper( static_cast< unsigned char >( c ) ) ;


    > > It's undefined behavior to call the std::toupper( int ) above
    > > with any negative value other than EOF, and char is often
    > > signed.


    > >> 10 int main() {
    > >> 11 string s("This is the zip code of Hodna 1223");
    > >> 12 cout << "original: " << s <<endl;
    > >> 13 transform(s.begin(), s.end(),s.begin(), toUpper);
    > >> 14 cout << "upper: " << s << endl;
    > >> 15 }


    > >> then:
    > >> gie@charon:~/Letters/src$ g++ t.cpp
    > >> gie@charon:~/Letters/src$ ./a.out
    > >> original: This is the zip code of Hodna 1223
    > >> upper: THIS IS THE ZIP CODE OF HODNA 1223
    > >> gie@charon:~/Letters/src$
    > >> Problem solved.


    > > If all the code has to handle is this one string, then there
    > > are much, much easier ways to do it. In general, the above
    > > code has undefined behavior.


    > Outside of resorting to C char types what would be the
    > efficient alternative? The above looks more nifty than what I
    > would have to do in straight C.


    There are two general solutions. One, as others have pointed
    out, is to wrap the ctype function, casting the argument to
    unsigned char in order to ensure that it will be in range. The
    other is to create a functional object which takes a locale as
    an argument (probably with a default to locale()), extracts the
    ctype facet, and uses this.

    Finally, of course, if portability is not a concern, and your
    compiler has an option to make char unsigned, you can use that,
    and:
    transform(s.begin(), s.end(),s.begin(), ::toupper);
    The undefined behavior only occurs if plain char is signed.
    (IMHO, this is, technically, the best option. It has a serious
    management problem, however, in that your code depends heavily
    on a compiler option, which someone in the future might change
    without checking. Perhaps with something like:
    #if CHAR_MIN != 0
    #error requires plain char to be unsigned, must use /J option
    #endif
    at the top of the file?)

    > > And of course, the reason why the code now compiles is
    > > because there is only one isUpper function, so overload
    > > resolution has no problem choosing.


    > First, I am a total C++ dumbkopf and only an old time C user
    > that likes to take advantages of some of C++ notational short
    > cuts. In this case I do not see where the overloading of
    > toupper is coming from.


    From the fact that the C++ standard (unlike the C standard)
    allows a standard header to include any other standard headers.
    And the standard header <locale> defines a template function
    toupper:
    template< typename CharT >
    CharT toupper( CharT, locale const& ) ;
    (in std::, of course). Given:
    transform(s.begin(), s.end(),s.begin(), toupper);
    after a "using namespace std;", or
    transform(s.begin(), s.end(),s.begin(), std::toupper);
    the compiler should take into account that this function
    template exists, and be unable to deduce the type of the fourth
    parameter. (For some reason, VC++ version 8 seems to ignore
    function templates when doing this type deduction. Which is not
    conform, but may be intentional, and not an error.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

    > From what you say it seems to imply that there are multiple
    > declarations of toupper---where?? I have only seen toupper used
    > in this basic example and each referred to cctype which I assumed
    > contained the *only* definition.


    > Thanks for your comments. They sparked me to look a little further.
    >
    > > --
    > > James Kanze (GABI Software) mailto:
    > > Conseils en informatique orient?e objet/
    > > Beratung in objektorientierter Datenverarbeitung
    > > 9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jan 8, 2008
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steffen Brinkmann

    <algorithm> transform modification

    Steffen Brinkmann, Sep 21, 2003, in forum: C++
    Replies:
    20
    Views:
    796
    Steffen Brinkmann
    Sep 24, 2003
  2. Patrick Guio

    STL transform algorithm

    Patrick Guio, Nov 2, 2005, in forum: C++
    Replies:
    9
    Views:
    570
    Clark S. Cox III
    Nov 2, 2005
  3. Piotr

    STL transform algorithm

    Piotr, Feb 14, 2006, in forum: C++
    Replies:
    5
    Views:
    451
    Daniel T.
    Feb 14, 2006
  4. Diego Martins

    Transform algorithm 1-n, n-1 or m-n

    Diego Martins, Oct 18, 2006, in forum: C++
    Replies:
    2
    Views:
    308
    Fraser Ross
    Oct 19, 2006
  5. suresh
    Replies:
    2
    Views:
    336
    suresh
    Dec 30, 2007
Loading...

Share This Page