Terminology in english :)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Taras_96

    Terminology in english :)

    Hi everyone,

    In me trying to find strtoupper wasn't working with transform (which
    I've fixed now), I came across the following message:

    | ------------------- cut here ---------------------
    |
    | #include <string>
    | #include <algorithm>
    | #include <cctype>
    | #include <iostream
    |
    | using namespace std;
    |
    | std::string& lower( std::string& p_str )
    | {
    | std::transform( p_str.begin(), p_str.end(), p_str.begin(),
    tolower );

    ^^^^^^^

    This ought to be a FAQ.

    Three facts:

    1) std::tolower (resp. std::toupper) is an overloaded function.
    2) C++ has no type for the set of overloaded functions.
    3) Template-argument deduction works by unifying the argument type
    with
    function parameter types.

    by point 2), point 3) cannot succeed, hence the error.

    -- Gaby

    =============== ==

    I don't really understand what points 2 & 3 are saying. Is point 3
    saying that if we have a templated function:

    <template X>foo(X x)

    Then when we write:

    foo('a')

    The compiler deduces that in this function call X refers to a char
    type?

    No idea what point #2 is saying :)

    On a related note:

    " transform(foo.b egin(), foo.end(), foo.begin(), (int(*)
    (int))std::tolo wer);

    The cast causes, on the one hand, an explicit overload resolution
    in favour of the function; it also allows the compiler to properly
    deduce the third argument to transform."

    What does he mean we talking about casting causing an explicit
    overload resolution in favour of the function?

    Cheers

    Taras

  • Victor Bazarov

    #2
    Re: Terminology in english :)

    Taras_96 wrote:
    Hi everyone,
    >
    In me trying to find strtoupper wasn't working with transform (which
    I've fixed now), I came across the following message:
    >
    >------------------- cut here ---------------------
    >>
    >#include <string>
    >#include <algorithm>
    >#include <cctype>
    >#include <iostream
    >>
    >using namespace std;
    >>
    >std::string& lower( std::string& p_str )
    >{
    > std::transform( p_str.begin(), p_str.end(), p_str.begin(),
    >tolower );
    >
    ^^^^^^^
    >
    This ought to be a FAQ.
    >
    Three facts:
    >
    1) std::tolower (resp. std::toupper) is an overloaded function.
    2) C++ has no type for the set of overloaded functions.
    3) Template-argument deduction works by unifying the argument type
    with
    function parameter types.
    >
    by point 2), point 3) cannot succeed, hence the error.
    >
    -- Gaby
    >
    =============== ==
    >
    I don't really understand what points 2 & 3 are saying. Is point 3
    saying that if we have a templated function:
    >
    <template X>foo(X x)
    Return value type is missing.
    >
    Then when we write:
    >
    foo('a')
    >
    The compiler deduces that in this function call X refers to a char
    type?
    Yes. It's called "template argument deduction from a function
    call".
    >
    No idea what point #2 is saying :)
    If I were to speculate, it might be saying that no overloading
    exists solely on the return value type. Or it might be saying
    that there is no generic type in the language formed from a set
    of overloaded functions (not sure what it might be useful for,
    however).
    >
    On a related note:
    >
    " transform(foo.b egin(), foo.end(), foo.begin(), (int(*)
    (int))std::tolo wer);
    >
    The cast causes, on the one hand, an explicit overload resolution
    in favour of the function; it also allows the compiler to properly
    deduce the third argument to transform."
    >
    What does he mean we talking about casting causing an explicit
    overload resolution in favour of the function?
    Overload resolution when conversion to a function pointer is used
    has to take the _destination_ty pe_ into consideration. For
    example:

    int foo(int); // line 1
    void foo(char);
    int main() {
    int (*p)(int) = foo; // the 'foo' from line 1 is picked
    }

    HTH

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • Gerhard Fiedler

      #3
      Re: Terminology in english :)

      On 2008-02-28 14:07:40, James Kanze wrote:
      >(int(*)(int))s td::tolower
      >What does he mean we talking about casting causing an explicit overload
      >resolution in favour of the function?
      >
      It means that in cases where the compiler cannot resolve overloading
      when taking the address of an overloaded function, the language has
      provided a hack so we can manually specify which function we want.
      Syntactically, it's a cast, but semantically, it doesn't do a
      conversion, but specifies what we expect the type to actually be.
      >
      (Note that this is a bit tricky. If I replace std::tolower with a
      function that isn't overloaded, and which has a different signature than
      the one given, it *is* a conversion.)
      Is there a way to explicitly specify which of the overloads to use that
      fails if there isn't an exact match?

      Gerhard

      Comment

      • Andrey Tarasevich

        #4
        Re: Terminology in english :)

        Gerhard Fiedler wrote:
        ...
        Is there a way to explicitly specify which of the overloads to use that
        fails if there isn't an exact match?
        ...
        Use explicit specification of template arguments instead of a cast - it will
        fail if there's no exact match

        std::transform<
        std::string::it erator,
        std::string::it erator,
        int(*)(int)>( p_str.begin(), p_str.end(), p_str.begin(), std::tolower )

        Unfortunately, in this case the ambiguous parameter is the last one of three,
        which means that we have to specify all of them explicitly.

        --
        Best regards,
        Andrey Tarasevich

        Comment

        • James Kanze

          #5
          Re: Terminology in english :)

          On Feb 29, 1:14 pm, Gerhard Fiedler <geli...@gmail. comwrote:
          On 2008-02-28 14:07:40, James Kanze wrote:
          (int(*)(int))st d::tolower
          What does he mean we talking about casting causing an
          explicit overload resolution in favour of the function?
          It means that in cases where the compiler cannot resolve
          overloading when taking the address of an overloaded
          function, the language has provided a hack so we can
          manually specify which function we want. Syntactically,
          it's a cast, but semantically, it doesn't do a conversion,
          but specifies what we expect the type to actually be.
          (Note that this is a bit tricky. If I replace std::tolower
          with a function that isn't overloaded, and which has a
          different signature than the one given, it *is* a
          conversion.)
          Is there a way to explicitly specify which of the overloads to
          use that fails if there isn't an exact match?
          Two casts, the first to specify the overload you want, and the
          second to do the conversion. You don't want this here,
          however; the only thing you can legally do with the converted
          value is cast it back to the original type, and transform isn't
          about to do that.

          --
          James Kanze (GABI Software) email:james.kan ze@gmail.com
          Conseils en informatique orientée objet/
          Beratung in objektorientier ter Datenverarbeitu ng
          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

          Comment

          • Andrey Tarasevich

            #6
            Re: Terminology in english :)

            Gerhard Fiedler wrote:
            ...
            Is there a way to explicitly specify which of the overloads to use that
            fails if there isn't an exact match?
            ...
            Actually, just using a 'static_cast' instead of the C-style cast should already
            achieve that. The original version does not fail if there isn't an exact match
            specifically because it uses a brutish C-style cast.

            --
            Best regards,
            Andrey Tarasevich

            Comment

            • Gerhard Fiedler

              #7
              Re: Terminology in english :)

              On 2008-02-29 13:34:31, Andrey Tarasevich wrote:
              >Is there a way to explicitly specify which of the overloads to use that
              >fails if there isn't an exact match?
              >
              Actually, just using a 'static_cast' instead of the C-style cast should already
              achieve that. The original version does not fail if there isn't an exact match
              specifically because it uses a brutish C-style cast.
              Is a "brutish C-style cast" <gthe same as a reinterpret_cas t?

              Thanks,
              Gerhard

              Comment

              • Bo Persson

                #8
                Re: Terminology in english :)

                Gerhard Fiedler wrote:
                On 2008-02-29 13:34:31, Andrey Tarasevich wrote:
                >
                >>Is there a way to explicitly specify which of the overloads to
                >>use that fails if there isn't an exact match?
                >>
                >Actually, just using a 'static_cast' instead of the C-style cast
                >should already achieve that. The original version does not fail if
                >there isn't an exact match specifically because it uses a brutish
                >C-style cast.
                >
                Is a "brutish C-style cast" <gthe same as a reinterpret_cas t?
                >
                No, it is rather a "whatever it takes"_cast. The compiler will have to
                do any combinations of C++ casts, or even worse things, to achive the
                just-do-it effect.

                Makes it hard to see what happens. :-)


                Bo Persson


                Comment

                • Jeff Schwab

                  #9
                  Re: Terminology in english :)

                  Gerhard Fiedler wrote:
                  On 2008-02-29 13:34:31, Andrey Tarasevich wrote:
                  >
                  >>Is there a way to explicitly specify which of the overloads to use that
                  >>fails if there isn't an exact match?
                  >Actually, just using a 'static_cast' instead of the C-style cast should already
                  >achieve that. The original version does not fail if there isn't an exact match
                  >specifically because it uses a brutish C-style cast.
                  >
                  Is a "brutish C-style cast" <gthe same as a reinterpret_cas t?
                  Aside from being difficult to grep for, and doing less than
                  reinterpret_cas t (et al) to make the programmer's intent clear, C-style
                  casts may ("oops") perform unintended conversions. For example, a
                  reinterpret_cas t won't cast away const, but a C-style cast might.

                  int main() {
                  int const i = 42;

                  // Won't compile.
                  // int j = reinterpret_cas t<int>(i);

                  // Equivalent to const_cast.
                  int k = (int) i;
                  }

                  Comment

                  • Gerhard Fiedler

                    #10
                    Re: Terminology in english :)

                    On 2008-03-01 13:12:27, Bo Persson wrote:
                    >Is a "brutish C-style cast" <gthe same as a reinterpret_cas t?
                    >
                    No, it is rather a "whatever it takes"_cast. The compiler will have to
                    do any combinations of C++ casts, or even worse things, to achive the
                    just-do-it effect.
                    Is there anything that couldn't be achieved with a combination of C++
                    casts? It seems that the only thing a reinterpret_cas t doesn't do is cast
                    away const (as Jeff explained), which can be done by a const_cast.

                    Gerhard

                    Comment

                    • Jerry Coffin

                      #11
                      Re: Terminology in english :)

                      In article <iqbnfsx7jqoy$. dlg@gelists.gma il.com>, gelists@gmail.c om
                      says...

                      [ ... ]
                      Is there anything that couldn't be achieved with a combination of C++
                      casts? It seems that the only thing a reinterpret_cas t doesn't do is cast
                      away const (as Jeff explained), which can be done by a const_cast.
                      Yes, there is (at least) one thing that can't be accomplished by a
                      combination of C++ casts (that can by a C cast). If you really care
                      about it, see:



                      --
                      Later,
                      Jerry.

                      The universe is a figment of its own imagination.

                      Comment

                      • Gerhard Fiedler

                        #12
                        Re: Terminology in english :)

                        On 2008-03-02 12:42:00, Jerry Coffin wrote:
                        >Is there anything that couldn't be achieved with a combination of C++
                        >casts? It seems that the only thing a reinterpret_cas t doesn't do is
                        >cast away const (as Jeff explained), which can be done by a const_cast.
                        >
                        Yes, there is (at least) one thing that can't be accomplished by a
                        combination of C++ casts (that can by a C cast). If you really care
                        about it, see:
                        >
                        http://groups.google.com/group/comp....827f55d5914188
                        Ahh... I didn't know this. Probably as rare as the need for a C-style cast,
                        though :)

                        Thanks a lot,
                        Gerhard

                        Comment

                        • Taras_96

                          #13
                          Re: Terminology in english :)

                          On Feb 29, 1:07 am, James Kanze <james.ka...@gm ail.comwrote:
                          >
                          While I'm at it: your code won't work anyway: you can't call the
                          one argument version of std::tolower with a dereferences string
                          iterator without incurring undefined behavior. You need to use
                          the two argument version (with a locale) in <locale>. (More
                          generally, you need to define what you really mean by "tolower".
                          There's not a one to one mapping, or even a many to one mapping,
                          of upper case to lower case: sometimes, the lower case version
                          of a string will result in a different number of characters, and
                          sometimes, the conversion will depend on the context.)
                          >
                          Could you explain this a bit further? You've kind of lost me :). Why
                          is the behaviour undefined?

                          Comment

                          • Taras_96

                            #14
                            Re: Terminology in english :)

                            On Mar 24, 9:34 pm, James Kanze <james.ka...@gm ail.comwrote:
                            >
                            Exactly. The compiler needs a known point to start from.
                            >
                            Thanks a lot James, you should be on experts exchange or something!

                            Comment

                            Working...